avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Stack usage under heavy inlining


From: David Brown
Subject: Re: [avr-gcc-list] Stack usage under heavy inlining
Date: Tue, 09 Sep 2008 09:45:19 +0200
User-agent: Thunderbird 2.0.0.16 (Windows/20080708)

Stu Bell wrote:
Oh, I see.  The inlining causes an "almost" static definition for the
locals in the functions.  As someone else said, the reuse of the stack
is disabled.
Wow, that's a good reason to avoid use of local variables in inlined
functions.  If it's possible.  :(  Yuck!

Best regards, Stu Bell DataPlay (DPHI, Inc.)


It's important to remember that this situation is actually a special case. The majority of functions, especially smaller ones (that are typically automatically inlined), have a small number of local variables that are mostly allocated in registers. These are handled perfectly well by gcc's inliner, using normal lifetime analysis so that registers are reused.

Inlining small functions can often lead to smaller code as well as faster code - you avoid the call overhead, and the compiler can make better use of registers. Inlining big functions that are only used once is also almost always a win - that's why it is done automatically on many optimisation levels. Of course, inlining plays havoc with your debugging, but that's another issue.

Personally, I have not noticed problems with stack usage with inlining. There is no good reason why there should be an issue - lifetime analysis of the local variables *should* ensure that gcc knows which variables are live and which are dead, and allow stack reuse. But there are definite limits to gcc's abilities here - it is easy to write code where the programmer knows that the stack area can be re-used, but the compiler fails to do so.

In the example below (compiled with avr 4.3.0 and -Os), functionD() generates code with only 32-byte stack frames, as one would like. functionE(), on the other hand, generates a 96-byte stack frame. I think this is evidence that it is gcc's normal lifetime analysis and/or stack reuse abilities that are the issue here, not anything related to inlining. In fact, the inlined version does a better job - perhaps the lifetime analysis is easier in that case. I would expect that any improvements to gcc that aid functionE() below will automatically benefit functionD() with inlined code as well.

mvh.,

David



#include <stdint.h>

extern int exFunc(uint8_t *p);

static int functionA(void) {
        uint8_t localA[32];
        return exFunc(localA);
}

static int functionB(void) {
        uint8_t localB[32];
        return exFunc(localB);
}

static int functionC(void) {
        uint8_t localC[32];
        return exFunc(localC);
}

int functionD(void) {
        int a = functionA();
        int b = functionB();
        int c = functionC();
        return a + b + c;
}

int functionE(void) {
        uint8_t localA[32];
        int a = exFunc(localA);

        uint8_t localB[32];
        int b = exFunc(localB);

        uint8_t localC[32];
        int c = exFunc(localC);

        return a + b + c;
}







reply via email to

[Prev in Thread] Current Thread [Next in Thread]