Tighten LRA cycling check
authorRichard Sandiford <richard.sandiford@linaro.org>
Sat, 6 Jan 2018 11:07:53 +0000 (11:07 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 6 Jan 2018 11:07:53 +0000 (11:07 +0000)
commitb4c969723c1e61dbdaadc61b0b5fd5393e9ff76e
tree19735df08600785a6e4ce432650c0ad8b1093509
parentb081a3764277fc23dc06ac6bbd2ba35fcf6fcc06
Tighten LRA cycling check

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++
------->    Cycle danger: overall += LRA_MAX_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.

2018-01-06  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.

From-SVN: r256312
gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/reg-alloc-1.c [new file with mode: 0644]