> >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
Ok. I was trying to understand the basic strategies of handling a tail-called function. Broadly speaking, [1]. In the case of normal tail-call, the stack of the caller is freed and then a jump to callee is made. [2]. Incase of a tail-recursive case, the recursion is made iterative. >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. > <snip> > >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. > Thanks. I tried various cases (mutually recursive functions, interrupts and signals, variable arguments). Required a bit of wandering through tree-tailcall.c to know what other cases are not qualified as tail-called ones(variable arguments is one such). The code generated is as expected. Coming to -mcall-prologues issue, I agree whenever prologue_saves and epilogue_restores, making the function qualified as a tail call is not ok (or it requires different handling). Going by the backend code, they are now emitted (prologue_saves and epilogue_restores) whenever -mcall-prologues is used. Ditto when callee-used registers are used for argument passing. I think it is a nice work! Anitha