aboutsummaryrefslogtreecommitdiff
path: root/gcc/ira.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 16:39:38 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 16:39:38 +0000
commit6d1e98dfd2bfce30640d71df355bedf114229744 (patch)
tree4fd650f51b146fd95f2345a09063f202a8768f53 /gcc/ira.c
parent7c3958812bd5e2e139c7f0adf8f03b505fda67f2 (diff)
downloadgcc-6d1e98dfd2bfce30640d71df355bedf114229744.zip
gcc-6d1e98dfd2bfce30640d71df355bedf114229744.tar.gz
gcc-6d1e98dfd2bfce30640d71df355bedf114229744.tar.bz2
Make ira call df_set_regs_ever_live for extra call-clobbered regs
If we support multiple ABIs in the same translation unit, it can sometimes be the case that a callee clobbers more registers than its caller is allowed to. We need to call df_set_regs_ever_live on these extra registers so that the prologue and epilogue code can handle them appropriately. This patch does that in IRA. I wanted to avoid another full instruction walk just for this, so I combined it with the existing set_paradoxical_subreg walk. This happens before the first calculation of elimination offsets. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * function-abi.h (function_abi_aggregator): New class. * function-abi.cc (function_abi_aggregator::caller_save_regs): New function. * ira.c (update_equiv_regs_prescan): New function. Call set_paradoxical_subreg here rather than... (update_equiv_regs): ...here. (ira): Call update_equiv_regs_prescan. From-SVN: r276339
Diffstat (limited to 'gcc/ira.c')
-rw-r--r--gcc/ira.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/gcc/ira.c b/gcc/ira.c
index 925ea26..3b4f9a8 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3362,6 +3362,37 @@ def_dominates_uses (int regno)
return true;
}
+/* Scan the instructions before update_equiv_regs. Record which registers
+ are referenced as paradoxical subregs. Also check for cases in which
+ the current function needs to save a register that one of its call
+ instructions clobbers.
+
+ These things are logically unrelated, but it's more efficient to do
+ them together. */
+
+static void
+update_equiv_regs_prescan (void)
+{
+ basic_block bb;
+ rtx_insn *insn;
+ function_abi_aggregator callee_abis;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ FOR_BB_INSNS (bb, insn)
+ if (NONDEBUG_INSN_P (insn))
+ {
+ set_paradoxical_subreg (insn);
+ if (CALL_P (insn))
+ callee_abis.note_callee_abi (insn_callee_abi (insn));
+ }
+
+ HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
+ if (!hard_reg_set_empty_p (extra_caller_saves))
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
+ if (TEST_HARD_REG_BIT (extra_caller_saves, regno))
+ df_set_regs_ever_live (regno, true);
+}
+
/* Find registers that are equivalent to a single value throughout the
compilation (either because they can be referenced in memory or are
set once from a single constant). Lower their priority for a
@@ -3378,15 +3409,6 @@ update_equiv_regs (void)
rtx_insn *insn;
basic_block bb;
- /* Scan insns and set pdx_subregs if the reg is used in a
- paradoxical subreg. Don't set such reg equivalent to a mem,
- because lra will not substitute such equiv memory in order to
- prevent access beyond allocated memory for paradoxical memory subreg. */
- FOR_EACH_BB_FN (bb, cfun)
- FOR_BB_INSNS (bb, insn)
- if (NONDEBUG_INSN_P (insn))
- set_paradoxical_subreg (insn);
-
/* Scan the insns and find which registers have equivalences. Do this
in a separate scan of the insns because (due to -fcse-follow-jumps)
a register can be set below its use. */
@@ -5276,6 +5298,7 @@ ira (FILE *f)
init_alias_analysis ();
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
reg_equiv = XCNEWVEC (struct equivalence, max_reg_num ());
+ update_equiv_regs_prescan ();
update_equiv_regs ();
/* Don't move insns if live range shrinkage or register