Remove global call sets: regrename.c
This patch makes regrename use a similar mask-and-clobber-set pair to IRA when tracking whether registers are clobbered by calls in a region. Testing for a nonzero ABI mask is equivalent to testing for a register that crosses a call. Since AArch64 and c6x use regrename.h, they need to be updated to include function-abi.h first. AIUI this is preferred over including function-abi.h in regrename.h. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * regrename.h (du_head::call_clobber_mask): New field. (du_head::need_caller_save_reg): Replace with... (du_head::call_abis): ...this new field. * regrename.c: Include function-abi.h. (call_clobbered_in_chain_p): New function. (check_new_reg_p): Use crtl->abi when deciding whether a register is free for use after RA. Use call_clobbered_in_chain_p to test whether a candidate register would be clobbered by a call. (find_rename_reg): Don't add call-clobber conflicts here. (rename_chains): Check call_abis instead of need_caller_save_reg. (merge_chains): Update for changes to du_head. (build_def_use): Use insn_callee_abi to get the ABI of the call insn target. Record the ABI identifier in call_abis and the set of fully or partially clobbered registers in call_clobber_mask. Add fully-clobbered registers to hard_conflicts here rather than in find_rename_reg. * config/aarch64/cortex-a57-fma-steering.c: Include function-abi.h. (rename_single_chain): Check call_abis instead of need_caller_save_reg. * config/aarch64/falkor-tag-collision-avoidance.c: Include function-abi.h. * config/c6x/c6x.c: Likewise. From-SVN: r276332
This commit is contained in:
parent
30503f4ea4
commit
0ce77f463d
@ -1,3 +1,27 @@
|
||||
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* regrename.h (du_head::call_clobber_mask): New field.
|
||||
(du_head::need_caller_save_reg): Replace with...
|
||||
(du_head::call_abis): ...this new field.
|
||||
* regrename.c: Include function-abi.h.
|
||||
(call_clobbered_in_chain_p): New function.
|
||||
(check_new_reg_p): Use crtl->abi when deciding whether a register
|
||||
is free for use after RA. Use call_clobbered_in_chain_p to test
|
||||
whether a candidate register would be clobbered by a call.
|
||||
(find_rename_reg): Don't add call-clobber conflicts here.
|
||||
(rename_chains): Check call_abis instead of need_caller_save_reg.
|
||||
(merge_chains): Update for changes to du_head.
|
||||
(build_def_use): Use insn_callee_abi to get the ABI of the call insn
|
||||
target. Record the ABI identifier in call_abis and the set of
|
||||
fully or partially clobbered registers in call_clobber_mask.
|
||||
Add fully-clobbered registers to hard_conflicts here rather
|
||||
than in find_rename_reg.
|
||||
* config/aarch64/cortex-a57-fma-steering.c: Include function-abi.h.
|
||||
(rename_single_chain): Check call_abis instead of need_caller_save_reg.
|
||||
* config/aarch64/falkor-tag-collision-avoidance.c: Include
|
||||
function-abi.h.
|
||||
* config/c6x/c6x.c: Likewise.
|
||||
|
||||
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* regcprop.c (copyprop_hardreg_forward_1): Use the recorded
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "insn-attr.h"
|
||||
#include "context.h"
|
||||
#include "tree-pass.h"
|
||||
#include "function-abi.h"
|
||||
#include "regrename.h"
|
||||
#include "aarch64-protos.h"
|
||||
|
||||
@ -281,7 +282,7 @@ rename_single_chain (du_head_p head, HARD_REG_SET *unavailable)
|
||||
{
|
||||
fprintf (dump_file, "Register %s in insn %d", reg_names[reg],
|
||||
INSN_UID (head->first->insn));
|
||||
if (head->need_caller_save_reg)
|
||||
if (head->call_abis)
|
||||
fprintf (dump_file, " crosses a call");
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "optabs.h"
|
||||
#include "regs.h"
|
||||
#include "recog.h"
|
||||
#include "function-abi.h"
|
||||
#include "regrename.h"
|
||||
#include "print-rtl.h"
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "sel-sched.h"
|
||||
#include "debug.h"
|
||||
#include "hw-doloop.h"
|
||||
#include "function-abi.h"
|
||||
#include "regrename.h"
|
||||
#include "dumpfile.h"
|
||||
#include "builtins.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "addresses.h"
|
||||
#include "cfganal.h"
|
||||
#include "tree-pass.h"
|
||||
#include "function-abi.h"
|
||||
#include "regrename.h"
|
||||
|
||||
/* This file implements the RTL register renaming pass of the compiler. It is
|
||||
@ -303,6 +304,18 @@ merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if (reg:MODE REGNO) would be clobbered by a call covered
|
||||
by THIS_HEAD. */
|
||||
|
||||
static bool
|
||||
call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
|
||||
unsigned int regno)
|
||||
{
|
||||
return call_clobbered_in_region_p (this_head->call_abis,
|
||||
this_head->call_clobber_mask,
|
||||
mode, regno);
|
||||
}
|
||||
|
||||
/* Check if NEW_REG can be the candidate register to rename for
|
||||
REG in THIS_HEAD chain. THIS_UNAVAILABLE is a set of unavailable hard
|
||||
registers. */
|
||||
@ -322,7 +335,7 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
|
||||
|| global_regs[new_reg + i]
|
||||
/* Can't use regs which aren't saved by the prologue. */
|
||||
|| (! df_regs_ever_live_p (new_reg + i)
|
||||
&& ! call_used_or_fixed_reg_p (new_reg + i))
|
||||
&& ! crtl->abi->clobbers_full_reg_p (new_reg + i))
|
||||
#ifdef LEAF_REGISTERS
|
||||
/* We can't use a non-leaf register if we're in a
|
||||
leaf function. */
|
||||
@ -337,11 +350,8 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
|
||||
for (tmp = this_head->first; tmp; tmp = tmp->next_use)
|
||||
if ((!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc))
|
||||
&& ! DEBUG_INSN_P (tmp->insn))
|
||||
|| (this_head->need_caller_save_reg
|
||||
&& ! (targetm.hard_regno_call_part_clobbered
|
||||
(0, reg, GET_MODE (*tmp->loc)))
|
||||
&& (targetm.hard_regno_call_part_clobbered
|
||||
(0, new_reg, GET_MODE (*tmp->loc)))))
|
||||
|| call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc),
|
||||
new_reg))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -363,12 +373,6 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
|
||||
int pass;
|
||||
int best_new_reg = old_reg;
|
||||
|
||||
/* Further narrow the set of registers we can use for renaming.
|
||||
If the chain needs a call-saved register, mark the call-used
|
||||
registers as unavailable. */
|
||||
if (this_head->need_caller_save_reg)
|
||||
*unavailable |= call_used_or_fixed_regs;
|
||||
|
||||
/* Mark registers that overlap this chain's lifetime as unavailable. */
|
||||
merge_overlapping_regs (unavailable, this_head);
|
||||
|
||||
@ -499,7 +503,7 @@ rename_chains (void)
|
||||
{
|
||||
fprintf (dump_file, "Register %s in insn %d",
|
||||
reg_names[reg], INSN_UID (this_head->first->insn));
|
||||
if (this_head->need_caller_save_reg)
|
||||
if (this_head->call_abis)
|
||||
fprintf (dump_file, " crosses a call");
|
||||
}
|
||||
|
||||
@ -680,7 +684,8 @@ merge_chains (du_head_p c1, du_head_p c2)
|
||||
c1->hard_conflicts |= c2->hard_conflicts;
|
||||
bitmap_ior_into (&c1->conflicts, &c2->conflicts);
|
||||
|
||||
c1->need_caller_save_reg |= c2->need_caller_save_reg;
|
||||
c1->call_clobber_mask |= c2->call_clobber_mask;
|
||||
c1->call_abis |= c2->call_abis;
|
||||
c1->cannot_rename |= c2->cannot_rename;
|
||||
}
|
||||
|
||||
@ -1834,9 +1839,15 @@ build_def_use (basic_block bb)
|
||||
requires a caller-saved reg. */
|
||||
if (CALL_P (insn))
|
||||
{
|
||||
function_abi callee_abi = insn_callee_abi (insn);
|
||||
class du_head *p;
|
||||
for (p = open_chains; p; p = p->next_chain)
|
||||
p->need_caller_save_reg = 1;
|
||||
{
|
||||
p->call_abis |= (1 << callee_abi.id ());
|
||||
p->call_clobber_mask
|
||||
|= callee_abi.full_and_partial_reg_clobbers ();
|
||||
p->hard_conflicts |= callee_abi.full_reg_clobbers ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 5: Close open chains that overlap writes. Similar to
|
||||
|
@ -41,9 +41,12 @@ public:
|
||||
bitmap_head conflicts;
|
||||
/* Conflicts with untracked hard registers. */
|
||||
HARD_REG_SET hard_conflicts;
|
||||
/* Which registers are fully or partially clobbered by the calls that
|
||||
the chain crosses. */
|
||||
HARD_REG_SET call_clobber_mask;
|
||||
|
||||
/* Nonzero if the chain crosses a call. */
|
||||
unsigned int need_caller_save_reg:1;
|
||||
/* A bitmask of ABIs used by the calls that the chain crosses. */
|
||||
unsigned int call_abis : NUM_ABI_IDS;
|
||||
/* Nonzero if the register is used in a way that prevents renaming,
|
||||
such as the SET_DEST of a CALL_INSN or an asm operand that used
|
||||
to be a hard register. */
|
||||
|
Loading…
Reference in New Issue
Block a user