On Thu, Sep 9, 2010 at 4:13 AM, Pat Haugen <pthau...@linux.vnet.ibm.com> wrote: > 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 think it makes sense in general. > 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. Hm, indeed - sinking of loads across a call might be still beneficial. > 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? Unfortunately not easily. What about just discounting all builtins? Richard. > > -Pat > > >