summaryrefslogtreecommitdiff
path: root/0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2025-02-28 10:03:49 +0000
committerCoprDistGit <infra@openeuler.org>2025-02-28 10:03:49 +0000
commit73127104a245052cd5cf29cdaaca3e5c32c70348 (patch)
tree8e28b63e478c43c252f18b49836dff7313affe54 /0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch
parent49d3feaf4665cdb07576fc1a2382a4d82a612d35 (diff)
automatic import of gccopeneuler24.03_LTS_SP1
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.patch211
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
+