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
>
>
>

Reply via email to