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;
}
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list