On Mon, Mar 24, 2014 at 12:44 PM, James Greenhalgh
<james.greenha...@arm.com> wrote:
>
> Hi,
>
> Consider this testcase:
>
>   extern void foo (int a, int b, int c, int d);
>
>   void
>   bar (int b, int c, int d)
>   {
>       foo (3, b, c, d);
>   }
>
> For many ABI's we will have on entry to the function
>
>   r0 = b
>   r1 = c
>   r2 = d
>
> If we process arguments to the call to foo left-to-right
> (PUSH_ARGS_REVERSED == 0) we assign temporaries, and then hard registers
> in this order:
>
>   t0 = 3
>   t1 = r0
>   t2 = r1
>   t3 = r2
>
>   r0 = t0
>   r1 = t1
>   r2 = t2
>   r3 = t3
>
> We can't eliminate any of these temporaries as their live ranges overlap.
>
> However, If we process the arguments right-to-left (PUSH_ARGS_REVERSED == 1),
> we get this order:
>
>   t0 = 3
>   t1 = r0
>   t2 = r1
>   t3 = r2
>
>   r3 = t3
>   r2 = t2
>   r1 = t1
>   r0 = t0
>
> And then we can start eliminating temporaries we don't need and get:
>
>   r3 = r2
>   r2 = r1
>   r1 = r0
>   r0 = 3
>
> Which is much neater.
>
> It seems to me that this would probably be of benefit on all targets.
>
> This would be an argument for setting PUSH_ARGS_REVERSED to 1 by default
> for all targets. However, this would have a perceivable impact on argument
> evaluation order (which is unspecified in C, but people have shown
> sensitivity to it changing in the past and we suspect some people may
> have built systems relying on the behviour... ho hum...).
>
> However, now that all side effects are handled when we are in SSA
> form, it should be possible to refactor calls.c and expr.c as if
> PUSH_ARGS_REVERSED were always defined to 1, without changing the
> argument evaluation order in gimplify.c.
>
> In this way, we have the best of both worlds; we maintain argument
> evaluation order and gain the optimizations given by removing
> overlapping live ranges for parameters.
>
> I've bootstrapped and regression tested this on x86, ARM and AArch64 - but
> I am well aware these are fairly standard targets, do you have any
> suggestions or comments on which targets this change will affect?
>
> If not, is this OK for stage-1?

Maybe somebody remembers why we have both paths.  I'd rather
make gimplification independent of this as well, choosing either
variant.

Do you have any hard numbers to compare?  Say cc1 code size,
when comparing PUSH_ARGS_REVERSED 1 vs 0?

Thanks,
Richard.

> Thanks,
> James
>
> ---
> gcc/
>
> 2014-03-21  James Greenhalgh  <james.greenha...@arm.com>
>
>         * calls.c (initialize_argument_information): Always treat
>         PUSH_ARGS_REVERSED as 1, simplify code accordingly.
>         (expand_call): Likewise.
>         (emit_library_call_calue_1): Likewise.
>         * expr.c (PUSH_ARGS_REVERSED): Do not define.
>         (emit_push_insn): Always treat PUSH_ARGS_REVERSED as 1, simplify
>         code accordingly.

Reply via email to