diff options
Diffstat (limited to '0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch')
-rw-r--r-- | 0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch b/0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch new file mode 100644 index 0000000..037a4f7 --- /dev/null +++ b/0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch @@ -0,0 +1,211 @@ +From a6964e11c7f624cdaed2c9608565a5968292b70f Mon Sep 17 00:00:00 2001 +From: Richard Sandiford <richard.sandiford@arm.com> +Date: Sat, 11 Nov 2023 17:28:58 +0000 +Subject: [PATCH 040/157] [Backport][SME] mode-switching: Pass set of live + registers to the needed hook + +Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=29d3e1892ebec8abce784077d1f1a3e21d763218 + +The emit hook already takes the set of live hard registers as input. +This patch passes it to the needed hook too. SME uses this to +optimise the mode choice based on whether state is live or dead. + +The main caller already had access to the required info, but the +special handling of return values did not. + +gcc/ + * target.def (mode_switching.needed): Add a regs_live parameter. + * doc/tm.texi: Regenerate. + * config/epiphany/epiphany-protos.h (epiphany_mode_needed): Update + accordingly. + * config/epiphany/epiphany.cc (epiphany_mode_needed): Likewise. + * config/epiphany/mode-switch-use.cc (insert_uses): Likewise. + * config/i386/i386.cc (ix86_mode_needed): Likewise. + * config/riscv/riscv.cc (riscv_mode_needed): Likewise. + * config/sh/sh.cc (sh_mode_needed): Likewise. + * mode-switching.cc (optimize_mode_switching): Likewise. + (create_pre_exit): Likewise, using the DF simulate functions + to calculate the required information. +--- + gcc/config/epiphany/epiphany-protos.h | 4 +++- + gcc/config/epiphany/epiphany.cc | 2 +- + gcc/config/epiphany/mode-switch-use.cc | 2 +- + gcc/config/i386/i386.cc | 2 +- + gcc/config/sh/sh.cc | 4 ++-- + gcc/doc/tm.texi | 5 +++-- + gcc/mode-switching.cc | 14 ++++++++++++-- + gcc/target.def | 5 +++-- + 8 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/gcc/config/epiphany/epiphany-protos.h b/gcc/config/epiphany/epiphany-protos.h +index 61b63234e..d463e5483 100644 +--- a/gcc/config/epiphany/epiphany-protos.h ++++ b/gcc/config/epiphany/epiphany-protos.h +@@ -44,7 +44,9 @@ extern void emit_set_fp_mode (int entity, int mode, int prev_mode, + #endif + extern void epiphany_insert_mode_switch_use (rtx_insn *insn, int, int); + extern void epiphany_expand_set_fp_mode (rtx *operands); +-extern int epiphany_mode_needed (int entity, rtx_insn *insn); ++#ifdef HARD_CONST ++extern int epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET); ++#endif + extern int epiphany_mode_after (int entity, int last_mode, rtx_insn *insn); + extern bool epiphany_epilogue_uses (int regno); + extern bool epiphany_optimize_mode_switching (int entity); +diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc +index f8c049340..be0fbc68c 100644 +--- a/gcc/config/epiphany/epiphany.cc ++++ b/gcc/config/epiphany/epiphany.cc +@@ -2400,7 +2400,7 @@ epiphany_mode_priority (int entity, int priority) + } + + int +-epiphany_mode_needed (int entity, rtx_insn *insn) ++epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET) + { + enum attr_fp_mode mode; + +diff --git a/gcc/config/epiphany/mode-switch-use.cc b/gcc/config/epiphany/mode-switch-use.cc +index 887550a33..cacb1ce5a 100644 +--- a/gcc/config/epiphany/mode-switch-use.cc ++++ b/gcc/config/epiphany/mode-switch-use.cc +@@ -58,7 +58,7 @@ insert_uses (void) + { + if (!INSN_P (insn)) + continue; +- mode = epiphany_mode_needed (e, insn); ++ mode = epiphany_mode_needed (e, insn, {}); + if (mode == no_mode) + continue; + if (target_insert_mode_switch_use) +diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc +index 60f3296b0..4d591d217 100644 +--- a/gcc/config/i386/i386.cc ++++ b/gcc/config/i386/i386.cc +@@ -14522,7 +14522,7 @@ ix86_i387_mode_needed (int entity, rtx_insn *insn) + prior to the execution of insn. */ + + static int +-ix86_mode_needed (int entity, rtx_insn *insn) ++ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET) + { + switch (entity) + { +diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc +index 03e1c04ec..85e83e12e 100644 +--- a/gcc/config/sh/sh.cc ++++ b/gcc/config/sh/sh.cc +@@ -195,7 +195,7 @@ static int calc_live_regs (HARD_REG_SET *); + static HOST_WIDE_INT rounded_frame_size (int); + static bool sh_frame_pointer_required (void); + static void sh_emit_mode_set (int, int, int, HARD_REG_SET); +-static int sh_mode_needed (int, rtx_insn *); ++static int sh_mode_needed (int, rtx_insn *, HARD_REG_SET); + static int sh_mode_after (int, int, rtx_insn *); + static int sh_mode_entry (int); + static int sh_mode_exit (int); +@@ -12529,7 +12529,7 @@ sh_emit_mode_set (int entity ATTRIBUTE_UNUSED, int mode, + } + + static int +-sh_mode_needed (int entity ATTRIBUTE_UNUSED, rtx_insn *insn) ++sh_mode_needed (int entity ATTRIBUTE_UNUSED, rtx_insn *insn, HARD_REG_SET) + { + return recog_memoized (insn) >= 0 ? get_attr_fp_mode (insn) : FP_MODE_NONE; + } +diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi +index 4788b3f7a..d8ac6c4d6 100644 +--- a/gcc/doc/tm.texi ++++ b/gcc/doc/tm.texi +@@ -10280,12 +10280,13 @@ known. Sets of a lower numbered entity will be emitted before + sets of a higher numbered entity to a mode of the same or lower priority. + @end deftypefn + +-@deftypefn {Target Hook} int TARGET_MODE_NEEDED (int @var{entity}, rtx_insn *@var{insn}) ++@deftypefn {Target Hook} int TARGET_MODE_NEEDED (int @var{entity}, rtx_insn *@var{insn}, HARD_REG_SET @var{regs_live}) + @var{entity} is an integer specifying a mode-switched entity. + If @code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this hook + to return the mode that @var{entity} must be switched into prior to the + execution of @var{insn}, or the number of modes if @var{insn} has no +-such requirement. ++such requirement. @var{regs_live} contains the set of hard registers ++that are live before @var{insn}. + @end deftypefn + + @deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn}) +diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc +index 9a6ba6cca..6bbda5058 100644 +--- a/gcc/mode-switching.cc ++++ b/gcc/mode-switching.cc +@@ -254,6 +254,9 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) + && GET_CODE (PATTERN (last_insn)) == USE + && GET_CODE ((ret_reg = XEXP (PATTERN (last_insn), 0))) == REG) + { ++ auto_bitmap live; ++ df_simulate_initialize_backwards (src_bb, live); ++ + int ret_start = REGNO (ret_reg); + int nregs = REG_NREGS (ret_reg); + int ret_end = ret_start + nregs; +@@ -262,6 +265,8 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) + bool forced_late_switch = false; + rtx_insn *before_return_copy; + ++ df_simulate_one_insn_backwards (src_bb, last_insn, live); ++ + do + { + rtx_insn *return_copy = PREV_INSN (last_insn); +@@ -269,6 +274,8 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) + int copy_start, copy_num; + int j; + ++ df_simulate_one_insn_backwards (src_bb, return_copy, live); ++ + if (NONDEBUG_INSN_P (return_copy)) + { + /* When using SJLJ exceptions, the call to the +@@ -368,11 +375,14 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) + the case for floating point on SH4 - then it might + be set by an arithmetic operation that needs a + different mode than the exit block. */ ++ HARD_REG_SET hard_regs_live; ++ REG_SET_TO_HARD_REG_SET (hard_regs_live, live); + for (j = n_entities - 1; j >= 0; j--) + { + int e = entity_map[j]; + int mode = +- targetm.mode_switching.needed (e, return_copy); ++ targetm.mode_switching.needed (e, return_copy, ++ hard_regs_live); + + if (mode != num_modes[e] + && mode != targetm.mode_switching.exit (e)) +@@ -609,7 +619,7 @@ optimize_mode_switching (void) + { + if (INSN_P (insn)) + { +- int mode = targetm.mode_switching.needed (e, insn); ++ int mode = targetm.mode_switching.needed (e, insn, live_now); + rtx link; + + if (mode != no_mode && mode != last_mode) +diff --git a/gcc/target.def b/gcc/target.def +index bbb482de6..06a52bdaf 100644 +--- a/gcc/target.def ++++ b/gcc/target.def +@@ -7003,8 +7003,9 @@ DEFHOOK + If @code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this hook\n\ + to return the mode that @var{entity} must be switched into prior to the\n\ + execution of @var{insn}, or the number of modes if @var{insn} has no\n\ +-such requirement.", +- int, (int entity, rtx_insn *insn), NULL) ++such requirement. @var{regs_live} contains the set of hard registers\n\ ++that are live before @var{insn}.", ++ int, (int entity, rtx_insn *insn, HARD_REG_SET regs_live), NULL) + + DEFHOOK + (after, +-- +2.33.0 + |