From 0ce77f463d1d150e70a91807502d628492ca7ae5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 30 Sep 2019 16:21:19 +0000 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 24 +++++++++++ gcc/config/aarch64/cortex-a57-fma-steering.c | 3 +- .../aarch64/falkor-tag-collision-avoidance.c | 1 + gcc/config/c6x/c6x.c | 1 + gcc/regrename.c | 41 ++++++++++++------- gcc/regrename.h | 7 +++- 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d1534e472c5..6458d2b2e3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2019-09-30 Richard Sandiford + + * 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 * regcprop.c (copyprop_hardreg_forward_1): Use the recorded diff --git a/gcc/config/aarch64/cortex-a57-fma-steering.c b/gcc/config/aarch64/cortex-a57-fma-steering.c index 3e890ad3de6..d8e6038d13c 100644 --- a/gcc/config/aarch64/cortex-a57-fma-steering.c +++ b/gcc/config/aarch64/cortex-a57-fma-steering.c @@ -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"); } diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.c b/gcc/config/aarch64/falkor-tag-collision-avoidance.c index 9faed40403c..35ca7923257 100644 --- a/gcc/config/aarch64/falkor-tag-collision-avoidance.c +++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.c @@ -38,6 +38,7 @@ #include "optabs.h" #include "regs.h" #include "recog.h" +#include "function-abi.h" #include "regrename.h" #include "print-rtl.h" diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index e593273bbf5..f8e8295245b 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -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" diff --git a/gcc/regrename.c b/gcc/regrename.c index 6a2442bdaa7..8c3bae8998c 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -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 diff --git a/gcc/regrename.h b/gcc/regrename.h index 2fe12d5aa61..a67896368a9 100644 --- a/gcc/regrename.h +++ b/gcc/regrename.h @@ -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. */ -- 2.30.2