+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.
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
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);
}
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))
{
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))
{
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;
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;
/* 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
(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 \
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;
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. */
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);
}
}
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 ();
}