Tighten LRA cycling check

Richard Sandiford richard.sandiford@linaro.org
Sat Jan 6 11:13:00 GMT 2018


Jeff Law <law@redhat.com> writes:
> On 01/04/2018 02:28 PM, Richard Sandiford wrote:
>> LRA has code to try to prevent cycling, by avoiding reloads that
>> look too similar to the instruction being reloaded.  E.g. if we
>> have a R<-C move for some constant C, reloading the source with
>> another R<-C move is unlikely to be a good idea.
>> 
>> However, this safeguard unnecessarily triggered in tests like
>> the one in the patch.  We started with instructions like:
>> 
>> (insn 12 9 13 5 (set (reg:DI 0 x0)
>>         (reg/f:DI 459)) "reg-alloc-1.c":18 47 {*movdi_aarch64}
>>      (expr_list:REG_EQUAL (symbol_ref:DI ("x00") [flags 0xc0]  <var_decl 0x7f3c03c1f510 x00>)
>>         (nil)))
>> 
>> where r459 didn't get allocated a register and is equivalent to
>> constant x00.  LRA would then handle it like this:
>> 
>> Changing pseudo 459 in operand 1 of insn 12 on equiv `x00'
>>             1 Non-pseudo reload: reject+=2
>>             1 Non input pseudo reload: reject++
>>           alt=0,overall=609,losers=1,rld_nregs=1
>> [...]
>>           alt=13,overall=9,losers=1,rld_nregs=1
>> [...]
>>          Choosing alt 13 in insn 12:  (0) r  (1) w {*movdi_aarch64}
>> 
>> In other words, to avoid loading the constant x00 into another GPR,
>> LRA decided instead to move it into a floating-point register,
>> then move that floating-point register into x0:
>> 
>>       Creating newreg=630, assigning class FP_REGS to r630
>>       Set class ALL_REGS for r631
>>    12: x0:DI=r630:DI
>>       REG_EQUAL `x00'
>>     Inserting insn reload before:
>>   815: r631:DI=high(`x00')
>>   816: r630:DI=r631:DI+low(`x00')
>>       REG_EQUAL `x00'
>> 
>> That's inefficient and doesn't really help to resolve a cycling
>> problem, since the r630 destination of 816 needs to be reloaded into
>> a GPR anyway.
>> 
>> The cycling check already had an exception for source values that are
>> the result of an elimination.  This patch extends it to include the
>> result of equivalence substitution.
>> 
>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
>> Also tested by comparing the before and after assembly output for at
>> least one target per CPU directory.  The targets most affected were:
>> 
>>   aarch64_be-linux-gn
>>   aarch64-linux-gnu
>>   powerpc-eabispe
>>   riscv32-elf
>>   riscv64-elf
>>   sparc64-linux-gnu
>>   sparc-linux-gnu
>>   spu-elf
>> 
>> for which it improved code size overall.  There were minor register
>> renaming differences on some other targets.  x86 and powerpc*-linux-gnu
>> targets were unaffected.
>> 
>> OK to install?
>> 
>> Richard
>> 
>> 
>> 2018-01-04  Richard Sandiford  <richard.sandiford@linaro.org>
>> 
>> gcc/
>> 	* lra-constraints.c (process_alt_operands): Test for the equivalence
>> 	substitutions when detecting a possible reload cycle.
>> 
>> gcc/testsuite/
>> 	* gcc.target/aarch64/reg-alloc-1.c: New test.
> OK.

Thanks.

> Presumably related to 83699?  Do you want to reference it in the
> ChangeLog?

It's actually an unrelated problem that I'd originally seen on SVE.
I guess I was just lucky to have two cycling bugs around the same time :-)

Richard



More information about the Gcc-patches mailing list