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