212 lines
8.4 KiB
Diff
212 lines
8.4 KiB
Diff
|
|
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
|
||
|
|
|