[Patch][AVR]: Support tail calls

Georg-Johann Lay avr@gjlay.de
Mon Mar 14 14:32:00 GMT 2011


Boyapati, Anitha schrieb:

> To be on same page, can you explain how gcc optimizes above case?

in

void bar0 (void);
int bar1 (int);

int foo (int x)
{
    bar0();
    return bar1 (x);
}

x must be saved somewhere. avr-gcc choses Y.
Compiled -Os -mmcu=atmega8 -fno-optimize-sibling-calls reads

foo:
	push r28	 ;
	push r29	 ;
.L__stack_usage = 2
	movw r28,r24	 ;  x, x
	rcall bar0	 ;
	movw r24,r28	 ; , x
	rcall bar1	 ;
	pop r29	 ;
	pop r28	 ;
	ret

and -Os -mmcu=atmega8 -foptimize-sibling-calls

foo:
	push r28	 ;
	push r29	 ;
.L__stack_usage = 2
	movw r28,r24	 ;  x, x
	rcall bar0	 ;
	movw r24,r28	 ; , x
	pop r29	 ;
	pop r28	 ;
	rjmp bar1	 ;

> As I understand, in a tail-call optimization, bar1 can return to
> the caller of foo(). There can be different cases of handling this.
> But how is this handled in gcc after recognizing that foo() is a
> candidate for tail call?

gcc recognizes most cases where tail call optimization must not be
applied. But in some cases backend has to impose more restrictions,
this is what TARGET_FUNCTION_OK_FOR_SIBCALL is for. E.g. An ISR must
not tail-call an ordinary function because the epilogues must be
compatible bit ISR resp. non-ISR have incompatible epilogues.

gcc also evaluates standard insns "sibcall", "sibcall_value",
"sibcall_epilogue" which are analoga to "call", "call_value",
"epilogue", resp.

> Also, I have applied the patch, and used it for a small test case
> as below:
> 
> int bar1(int x) { x++; return x; }
> 
> int foo (int x) { return bar1 (x); }
> 
> int main() { volatile int i; return foo(i);
> 
> }
> 
> avr-gcc -S -foptimize-sibling-calls tail-call.c
> 
> 
> I find no difference in the code generated with and without tail
> call optimization. (I am assuming -foptimize-sibling-calls should
> turn on this). Let me know if I am doing something wrong.
> 
> Anitha

As with all other optimization options/passes, they are only applied
in the presence of optimization, i.e. with -O0 options like
-foptimize-sibling-calls have no effect. You will have to specify at
least -O1 to see effects.

Johann



More information about the Gcc-patches mailing list