gcc/0140-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch
2024-11-21 11:35:14 +08:00

178 lines
7.4 KiB
Diff

From 4457604c11c0a32f3736d73429d1e5fb7baae3a5 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 041/157] [Backport][SME] mode-switching: Pass the set of live
registers to the after hook
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=93d65f39bc5c3dc318deb6da0e3633f3a4c6c34d
This patch passes the set of live hard registers to the after hook,
like the previous one did for the needed hook.
gcc/
* target.def (mode_switching.after): Add a regs_live parameter.
* doc/tm.texi: Regenerate.
* config/epiphany/epiphany-protos.h (epiphany_mode_after): Update
accordingly.
* config/epiphany/epiphany.cc (epiphany_mode_needed): Likewise.
(epiphany_mode_after): Likewise.
* config/i386/i386.cc (ix86_mode_after): Likewise.
* config/riscv/riscv.cc (riscv_mode_after): Likewise.
* config/sh/sh.cc (sh_mode_after): Likewise.
* mode-switching.cc (optimize_mode_switching): Likewise.
---
gcc/config/epiphany/epiphany-protos.h | 3 ++-
gcc/config/epiphany/epiphany.cc | 5 +++--
gcc/config/i386/i386.cc | 2 +-
gcc/config/sh/sh.cc | 5 +++--
gcc/doc/tm.texi | 4 +++-
gcc/mode-switching.cc | 8 ++++----
gcc/target.def | 4 +++-
7 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/gcc/config/epiphany/epiphany-protos.h b/gcc/config/epiphany/epiphany-protos.h
index d463e5483..6326b7e80 100644
--- a/gcc/config/epiphany/epiphany-protos.h
+++ b/gcc/config/epiphany/epiphany-protos.h
@@ -46,8 +46,9 @@ extern void epiphany_insert_mode_switch_use (rtx_insn *insn, int, int);
extern void epiphany_expand_set_fp_mode (rtx *operands);
#ifdef HARD_CONST
extern int epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET);
+extern int epiphany_mode_after (int entity, int last_mode, 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);
extern bool epiphany_is_interrupt_p (tree);
diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
index be0fbc68c..62636b1ec 100644
--- a/gcc/config/epiphany/epiphany.cc
+++ b/gcc/config/epiphany/epiphany.cc
@@ -2437,7 +2437,7 @@ epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
return 2;
case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
- mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn);
+ mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn, {});
/* Fall through. */
case EPIPHANY_MSW_ENTITY_NEAREST:
case EPIPHANY_MSW_ENTITY_TRUNC:
@@ -2498,7 +2498,8 @@ epiphany_mode_entry_exit (int entity, bool exit)
}
int
-epiphany_mode_after (int entity, int last_mode, rtx_insn *insn)
+epiphany_mode_after (int entity, int last_mode, rtx_insn *insn,
+ HARD_REG_SET)
{
/* We have too few call-saved registers to hope to keep the masks across
calls. */
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 4d591d217..593185fa6 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -14583,7 +14583,7 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
/* Return the mode that an insn results in. */
static int
-ix86_mode_after (int entity, int mode, rtx_insn *insn)
+ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
{
switch (entity)
{
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index 85e83e12e..74d61c43b 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -196,7 +196,7 @@ 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 *, HARD_REG_SET);
-static int sh_mode_after (int, int, rtx_insn *);
+static int sh_mode_after (int, int, rtx_insn *, HARD_REG_SET);
static int sh_mode_entry (int);
static int sh_mode_exit (int);
static int sh_mode_priority (int entity, int n);
@@ -12535,7 +12535,8 @@ sh_mode_needed (int entity ATTRIBUTE_UNUSED, rtx_insn *insn, HARD_REG_SET)
}
static int
-sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn)
+sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn,
+ HARD_REG_SET)
{
if (TARGET_HITACHI && recog_memoized (insn) >= 0 &&
get_attr_fp_set (insn) != FP_SET_NONE)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d8ac6c4d6..7fce485b2 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10289,12 +10289,14 @@ 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})
+@deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn}, HARD_REG_SET @var{regs_live})
@var{entity} is an integer specifying a mode-switched entity.
If this hook is defined, it is evaluated for every @var{insn} during mode
switching. It returns the mode that @var{entity} is in after @var{insn}
has been executed. @var{mode} is the mode that @var{entity} was in
before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}.
+@var{regs_live} is the set of hard registers that are live after @var{insn}
+has been executed.
@var{mode} is equal to the number of modes defined for @var{entity}
if the mode before @var{insn} is unknown. The hook should likewise return
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index 6bbda5058..4f0445894 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -631,10 +631,6 @@ optimize_mode_switching (void)
last_mode = mode;
}
- if (targetm.mode_switching.after)
- last_mode = targetm.mode_switching.after (e, last_mode,
- insn);
-
/* Update LIVE_NOW. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -644,6 +640,10 @@ optimize_mode_switching (void)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_UNUSED)
reg_dies (XEXP (link, 0), &live_now);
+
+ if (targetm.mode_switching.after)
+ last_mode = targetm.mode_switching.after (e, last_mode,
+ insn, live_now);
}
}
diff --git a/gcc/target.def b/gcc/target.def
index 06a52bdaf..67c20bbb0 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7014,6 +7014,8 @@ If this hook is defined, it is evaluated for every @var{insn} during mode\n\
switching. It returns the mode that @var{entity} is in after @var{insn}\n\
has been executed. @var{mode} is the mode that @var{entity} was in\n\
before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}.\n\
+@var{regs_live} is the set of hard registers that are live after @var{insn}\n\
+has been executed.\n\
\n\
@var{mode} is equal to the number of modes defined for @var{entity}\n\
if the mode before @var{insn} is unknown. The hook should likewise return\n\
@@ -7021,7 +7023,7 @@ the number of modes if it does not know what mode @var{entity} has after\n\
@var{insn}.\n\
\n\
Not defining the hook is equivalent to returning @var{mode}.",
- int, (int entity, int mode, rtx_insn *insn), NULL)
+ int, (int entity, int mode, rtx_insn *insn, HARD_REG_SET regs_live), NULL)
DEFHOOK
(entry,
--
2.33.0