Add an "early rematerialisation" pass
commit62958b223cb5a7b2ac960c4573bcf1477d0ad309
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jan 2018 18:00:51 +0000 (13 18:00 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jan 2018 18:00:51 +0000 (13 18:00 +0000)
tree9fcd4a856308532c0061509406f541b072746f44
parent53771608ba9ca0aa91d89fa7d228a877016da3f7
Add an "early rematerialisation" pass

This patch looks for pseudo registers that are live across a call
and for which no call-preserved hard registers exist.  It then
recomputes the pseudos as necessary to ensure that they are no
longer live across a call.  The comment at the head of the file
describes the approach.

A new target hook selects which modes should be treated in this way.
By default none are, in which case the pass is skipped very early.

It might also be worth looking for cases like:

   C1: R1 := f (...)
   ...
   C2: R2 := f (...)
   C3: R1 := C2

and giving the same value number to C1 and C3, effectively treating
it like:

   C1: R1 := f (...)
   ...
   C2: R2 := f (...)
   C3: R1 := f (...)

Another (much more expensive) enhancement would be to apply value
numbering to all pseudo registers (not just rematerialisation
candidates), so that we can handle things like:

  C1: R1 := f (...R2...)
  ...
  C2: R1 := f (...R3...)

where R2 and R3 hold the same value.  But the current pass seems
to catch the vast majority of cases.

2018-01-13  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* Makefile.in (OBJS): Add early-remat.o.
* target.def (select_early_remat_modes): New hook.
* doc/tm.texi.in (TARGET_SELECT_EARLY_REMAT_MODES): New hook.
* doc/tm.texi: Regenerate.
* targhooks.h (default_select_early_remat_modes): Declare.
* targhooks.c (default_select_early_remat_modes): New function.
* timevar.def (TV_EARLY_REMAT): New timevar.
* passes.def (pass_early_remat): New pass.
* tree-pass.h (make_pass_early_remat): Declare.
* early-remat.c: New file.
* config/aarch64/aarch64.c (aarch64_select_early_remat_modes): New
function.
(TARGET_SELECT_EARLY_REMAT_MODES): Define.

gcc/testsuite/
* gcc.target/aarch64/sve/spill_1.c: Also test that no predicates
are spilled.
* gcc.target/aarch64/sve/spill_2.c: New test.
* gcc.target/aarch64/sve/spill_3.c: Likewise.
* gcc.target/aarch64/sve/spill_4.c: Likewise.
* gcc.target/aarch64/sve/spill_5.c: Likewise.
* gcc.target/aarch64/sve/spill_6.c: Likewise.
* gcc.target/aarch64/sve/spill_7.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@256636 138bc75d-0d04-0410-961f-82ee72b054a4
20 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/config/aarch64/aarch64.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/early-remat.c [new file with mode: 0644]
gcc/passes.def
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/sve/spill_1.c
gcc/testsuite/gcc.target/aarch64/sve/spill_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/spill_3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/spill_4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/spill_5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/spill_6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/spill_7.c [new file with mode: 0644]
gcc/timevar.def
gcc/tree-pass.h