diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-09-10 18:56:26 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-09-10 18:56:26 +0000 |
commit | df1f0eef67939274e9ddd3df426e8dfc5184086b (patch) | |
tree | 5c82b08c38893696032489e881bf32e860f507a2 /gcc | |
parent | 031e8857886b91da290ffb03d9027424566e5da3 (diff) | |
download | gcc-df1f0eef67939274e9ddd3df426e8dfc5184086b.zip gcc-df1f0eef67939274e9ddd3df426e8dfc5184086b.tar.gz gcc-df1f0eef67939274e9ddd3df426e8dfc5184086b.tar.bz2 |
Remove call_fixed_reg_set
On targets that use reload, call_fixed_reg_set is structurally:
fixed_reg_set -- reginfo.c
| (call_used_reg_set & ~have_save_mode) -- first loop in init_caller_save
| ~have_save_insn -- final loop in init_caller_save
(where "have_save_mode" and "have_save_insn" are just my names).
But the final loop in init_caller_save does:
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 1; j <= MOVE_MAX_WORDS; j++)
if (reg_save_code (i,regno_save_mode[i][j]) == -1)
This last condition ought to be true whenever:
regno_save_mode[i][j] == VOIDmode
since either targetm.hard_regno_mode_ok (i, VOIDmode) should be
false or the VOIDmode save & restore shouldn't match any move insn.
And after the first loop, regno_save_mode[i][j] == VOIDmode whenever
!call_used_regs[i]. So the above is actually:
fixed_reg_set
| (call_used_reg_set & ~have_save_mode)
| (~call_used_reg_set | ~have_save_insn)
which simplifies to:
fixed_reg_set -- reginfo.c
| ~have_save_mode -- first loop in init_caller_save
| ~have_save_insn -- final loop in init_caller_save
| ~call_used_reg_set -- final loop in init_caller_save
So:
~call_fixed_reg_set == (~fixed_reg_set
& have_save_mode
& have_save_insn
& call_used_reg_set) [A]
All users have the form:
(call_used_reg_set or some subset) & ~(call_fixed_reg_set | ...)
i.e.:
(call_used_reg_set or some subset) & ~call_fixed_reg_set & ~(...)
We can therefore drop the "& call_used_reg_set" from [A], leaving:
~fixed_reg_set & have_save_mode & have_save_insn
This patch combines have_save_mode & have_save_insn into a single
condition "a save is possible", represented as savable_regs.
We can then substitute:
~call_fixed_reg_set --> ~fixed_reg_set & savable_regs
(registers we can actually save around calls)
The patch also sets regno_save_mode[i][j] for all registers,
in case non-default ABIs require a save when the default ABI
doesn't. This ensures that savable_regs (like fixed_reg_set but
unlike call_fixed_reg_set) isn't affected by the ABI. This only
becomes significant with later patches and at this point is just
a simplification.
Since init_caller_save is only called for reload targets,
the default assumption for LRA is that all registers are savable,
just like the default assumption before the patch was that
(~)call_fixed_reg_set == (~)fixed_reg_set.
2019-09-10 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* hard-reg-set.h (target_hard_regs::x_call_fixed_reg_set): Delete.
(target_hard_regs::x_savable_regs): New field.
(call_fixed_reg_set): Delete.
(savable_regs): New macro,
* reginfo.c (globalize_reg): Don't set call_fixed_reg_set.
(init_reg_sets_1): Likewise. Initialize savable_regs.
* caller-save.c (init_caller_save): Invoke HARD_REGNO_CALLER_SAVE_MODE
for all registers. Set savable_regs instead of call_fixed_reg_set.
(setup_save_areas, save_call_clobbered_regs): Replace uses of
~call_fixed_reg_set with ~fixed_reg_set & savable_regs.
* config/sh/sh.c (output_stack_adjust): Likewise.
From-SVN: r275598
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/caller-save.c | 36 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 4 | ||||
-rw-r--r-- | gcc/hard-reg-set.h | 18 | ||||
-rw-r--r-- | gcc/reginfo.c | 5 |
5 files changed, 42 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56f99f0..aee3190 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,19 @@ 2019-09-10 Richard Sandiford <richard.sandiford@arm.com> + * hard-reg-set.h (target_hard_regs::x_call_fixed_reg_set): Delete. + (target_hard_regs::x_savable_regs): New field. + (call_fixed_reg_set): Delete. + (savable_regs): New macro, + * reginfo.c (globalize_reg): Don't set call_fixed_reg_set. + (init_reg_sets_1): Likewise. Initialize savable_regs. + * caller-save.c (init_caller_save): Invoke HARD_REGNO_CALLER_SAVE_MODE + for all registers. Set savable_regs instead of call_fixed_reg_set. + (setup_save_areas, save_call_clobbered_regs): Replace uses of + ~call_fixed_reg_set with ~fixed_reg_set & savable_regs. + * config/sh/sh.c (output_stack_adjust): Likewise. + +2019-09-10 Richard Sandiford <richard.sandiford@arm.com> + * config/c6x/c6x-protos.h (c6x_set_return_address): Declare. * config/c6x/c6x.h (REGNO_REG_CLASS): Move implementation to * config/c6x/c6x.c (c6x_regno_reg_class): ...this new function. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 8c88af9..05fbc44 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -198,23 +198,12 @@ init_caller_save (void) we can't have the register live over calls. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - { - if (call_used_regs[i] - && !TEST_HARD_REG_BIT (call_fixed_reg_set, i)) - { - for (j = 1; j <= MOVE_MAX_WORDS; j++) - { - regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, - VOIDmode); - if (regno_save_mode[i][j] == VOIDmode && j == 1) - { - SET_HARD_REG_BIT (call_fixed_reg_set, i); - } - } - } - else - regno_save_mode[i][1] = VOIDmode; - } + for (j = 1; j <= MOVE_MAX_WORDS; j++) + { + regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, VOIDmode); + if (regno_save_mode[i][j] == VOIDmode && j == 1) + CLEAR_HARD_REG_BIT (savable_regs, i); + } /* The following code tries to approximate the conditions under which we can easily save and restore a register without scratch registers or @@ -276,7 +265,7 @@ init_caller_save (void) regno_save_mode[i][j] = VOIDmode; if (j == 1) { - SET_HARD_REG_BIT (call_fixed_reg_set, i); + CLEAR_HARD_REG_BIT (savable_regs, i); if (call_used_regs[i]) SET_HARD_REG_BIT (no_caller_save_reg_set, i); } @@ -455,8 +444,8 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - used_regs &= ~(call_fixed_reg_set | this_insn_sets); - hard_regs_to_save &= used_regs; + used_regs &= ~(fixed_reg_set | this_insn_sets); + hard_regs_to_save &= used_regs & savable_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -539,8 +528,8 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - used_regs &= ~(call_fixed_reg_set | this_insn_sets); - hard_regs_to_save &= used_regs; + used_regs &= ~(fixed_reg_set | this_insn_sets); + hard_regs_to_save &= used_regs & savable_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -850,9 +839,10 @@ save_call_clobbered_regs (void) note_stores (insn, mark_set_regs, &this_insn_sets); /* Compute which hard regs must be saved before this call. */ - hard_regs_to_save &= ~(call_fixed_reg_set + hard_regs_to_save &= ~(fixed_reg_set | this_insn_sets | hard_regs_saved); + hard_regs_to_save &= savable_regs; get_call_reg_set_usage (insn, &call_def_reg_set, call_used_reg_set); hard_regs_to_save &= call_def_reg_set; diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index b2fb56c..7f88180 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6707,7 +6707,9 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { - HARD_REG_SET temps = call_used_reg_set & ~call_fixed_reg_set; + HARD_REG_SET temps = (call_used_reg_set + & ~fixed_reg_set + & savable_regs); if (epilogue_p > 0) { int nreg = 0; diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 274956e..4c8da3a 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -400,11 +400,15 @@ struct target_hard_regs { /* The same info as a HARD_REG_SET. */ HARD_REG_SET x_call_used_reg_set; - /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or - a function value return register or TARGET_STRUCT_VALUE_RTX or - STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities - across calls even if we are willing to save and restore them. */ - HARD_REG_SET x_call_fixed_reg_set; + /* For targets that use reload rather than LRA, this is the set + of registers that we are able to save and restore around calls + (i.e. those for which we know a suitable mode and set of + load/store instructions exist). For LRA targets it contains + all registers. + + This is legacy information and should be removed if all targets + switch to LRA. */ + HARD_REG_SET x_savable_regs; /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but only if they are not merely part of that set because they are global @@ -482,8 +486,8 @@ extern struct target_hard_regs *this_target_hard_regs; (this_target_hard_regs->x_call_really_used_regs) #define call_used_reg_set \ (this_target_hard_regs->x_call_used_reg_set) -#define call_fixed_reg_set \ - (this_target_hard_regs->x_call_fixed_reg_set) +#define savable_regs \ + (this_target_hard_regs->x_savable_regs) #define regs_invalidated_by_call \ (this_target_hard_regs->x_regs_invalidated_by_call) #define no_caller_save_reg_set \ diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 48a3f66..b72a567 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -351,7 +351,6 @@ init_reg_sets_1 (void) CLEAR_HARD_REG_SET (fixed_reg_set); CLEAR_HARD_REG_SET (call_used_reg_set); - CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); operand_reg_set &= accessible_reg_set; @@ -417,7 +416,7 @@ init_reg_sets_1 (void) SET_HARD_REG_BIT (regs_invalidated_by_call, i); } - call_fixed_reg_set = fixed_reg_set; + SET_HARD_REG_SET (savable_regs); fixed_nonglobal_reg_set = fixed_reg_set; /* Preserve global registers if called more than once. */ @@ -428,7 +427,6 @@ init_reg_sets_1 (void) fixed_regs[i] = call_used_regs[i] = 1; SET_HARD_REG_BIT (fixed_reg_set, i); SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); } } @@ -782,7 +780,6 @@ globalize_reg (tree decl, int i) SET_HARD_REG_BIT (fixed_reg_set, i); SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); reinit_regs (); } |