Question on TER

Pat Haugen pthaugen@linux.vnet.ibm.com
Thu Sep 9 02:13:00 GMT 2010


  I'm looking into a case where TER is forward propagating a series of 
additions across a call.

extern void foo(void);
int bar(int a, int b, int c, int d, int e, int f, int g, int h) {
   int ret;
   ret = a + b + c + d + e + f + g + h;
   foo();
   return ret;  /* 'ret' use replaced by rhs above */
}

Unfortunately by moving all the additions across the call we've extended 
the lifetimes of the parm regs across the call also and therefor they 
need to be copied into callee-saved regs to preserve their value across 
the call, which means bar() will have save/restore code for 8 regs 
instead of just 1 (to thold the result across the call).

I tried hacking tree-ssa-ter.c to not perform the replacement if the def 
and use cross a call (i.e. cross an is_gimple_call() stmt), but ran into 
cases where we don't do a valid replacement because things like 
__builtin_sqrtf()/__builtin_powf() are marked as calls but expand to 
simple instructions (on PPC anyway).  The __builtin_powf() calls were 
actually introduced on a transformation of y*y => __builtin_powf(y,2.0).

A couple of questions:

1) Is this a valid optimization in general to attempt wrt other targets 
(i.e. prevent replacement across calls)?  I assume this could further be 
refined so that we still do replacement across calls if the source 
operands of the expression are already live at the use point, but 
haven't looked into that.

2) Is there a way to recognize the __builtin_XXX() calls such that we 
know they result in simple insns an not a real call?


-Pat




More information about the Gcc mailing list