From df1f0eef67939274e9ddd3df426e8dfc5184086b Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:26 +0000 Subject: 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 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 --- gcc/hard-reg-set.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'gcc/hard-reg-set.h') 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 \ -- cgit v1.1