diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-13 18:00:51 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-13 18:00:51 +0000 |
commit | 5cce817119cd31d18fbfc1c8245519d86b5e9480 (patch) | |
tree | 9fcd4a856308532c0061509406f541b072746f44 /gcc/doc/tm.texi | |
parent | d1d20a49a788bdb82f09ada6377d932ceac07934 (diff) | |
download | gcc-5cce817119cd31d18fbfc1c8245519d86b5e9480.zip gcc-5cce817119cd31d18fbfc1c8245519d86b5e9480.tar.gz gcc-5cce817119cd31d18fbfc1c8245519d86b5e9480.tar.bz2 |
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.
From-SVN: r256636
Diffstat (limited to 'gcc/doc/tm.texi')
-rw-r--r-- | gcc/doc/tm.texi | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index faf7b8b..491f9c4 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2774,6 +2774,17 @@ details. With LRA, the default is to use @var{mode} unmodified. @end deftypefn +@deftypefn {Target Hook} void TARGET_SELECT_EARLY_REMAT_MODES (sbitmap @var{modes}) +On some targets, certain modes cannot be held in registers around a +standard ABI call and are relatively expensive to spill to the stack. +The early rematerialization pass can help in such cases by aggressively +recomputing values after calls, so that they don't need to be spilled. + +This hook returns the set of such modes by setting the associated bits +in @var{modes}. The default implementation selects no modes, which has +the effect of disabling the early rematerialization pass. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_CLASS_LIKELY_SPILLED_P (reg_class_t @var{rclass}) A target hook which returns @code{true} if pseudos that have been assigned to registers of class @var{rclass} would likely be spilled because |