File main.c: extern int h (int func (int)); int g2 (int c) { return c; } int f (int a, int b) { int g1 (int c) { return c; } return h (g1); } Command: gcc -S -Os -fomit-frame-pointer main.c File main.s: .file "main.c" .text .globl g2 .type g2,@function g2: movl 4(%esp), %eax ret .Lfe1: .size g2,.Lfe1-g2 .type g1.0,@function g1.0: pushl %ecx movl 8(%esp), %eax popl %edx ret .Lfe2: .size g1.0,.Lfe2-g1.0 .globl f .type f,@function f: subl $12, %esp leal 12(%esp), %ecx movl $g1.0+2, %edx movb $-71, (%esp) movl %esp, %eax subl %ecx, %edx movl %ecx, 1(%esp) movb $-23, 5(%esp) movl %edx, 6(%esp) pushl %eax call h addl $16, %esp ret .Lfe3: .size f,.Lfe3-f .ident "GCC: (GNU) 3.2.1" Command: ppc-elf-gcc -S -Os -fomit-frame-pointer main.c File main.s: .file "main.c" .section ".text" .align 2 .globl g2 .type g2,@function g2: blr .Lfe1: .size g2,.Lfe1-g2 .align 2 .type g1.0,@function g1.0: stwu 1,-16(1) addi 1,1,16 blr .Lfe2: .size g1.0,.Lfe2-g1.0 .globl __trampoline_setup .align 2 .globl f .type f,@function f: stwu 1,-64(1) lis 5,g1.0@ha mflr 0 la 5,g1.0@l(5) addi 3,1,8 li 4,40 mr 6,3 stw 0,68(1) crxor 6,6,6 bl __trampoline_setup addi 3,1,8 bl h lwz 0,68(1) addi 1,1,64 mtlr 0 blr .Lfe3: .size f,.Lfe3-f .ident "GCC: (GNU) 3.2.1" Note: Pay attention to difference between codes generated for function g1() and g2(). Release: 3.2.1 Environment: Configured with: ../gcc-3.2.1/configure --prefix=/home/crossGCC/native --exec_prefix=/home/crossGCC/native --with-local-prefix=/home/crossGCC/native --enable-languages=c,c++ -v and Configured with: ../gcc-3.2.1/configure --with-newlib --enable-target-optspace --target=ppc-elf --prefix=/home/crossGCC/ppc-elf --exec_prefix=/home/crossGCC/ppc-elf --with-local-prefix=/home/crossGCC/ppc-elf --program-prefix=ppc-elf- --enable-languages=c,c++ -v
Confirmed still present with gcc 3.3. branch and mainline (20030513). Dara
Note the PPC only happens on powerpc-elf and powerpc-eabi, it does not happen on powerpc- darwin6.6 or powerpc-aix5.1.
Looks like this is an effect of the SYSV ABI.
This is because g1 is allocated space on the stack as a result of the following code in expand_function_start. If a function has local variables (including hidden ones like this one) then it needs a stack frame. Other ABIs can create leaf functions having local vars without necessarily creating a stack frame. /* If function gets a static chain arg, store it in the stack frame. Do this first, so it gets the first stack slot offset. */ if (current_function_needs_context) { last_ptr = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
Fixed in 4.0 by the tree-ssa merge.