]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mode-switching: Pass set of live registers to the needed hook
authorRichard Sandiford <richard.sandiford@arm.com>
Sat, 11 Nov 2023 17:28:58 +0000 (17:28 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Sat, 11 Nov 2023 17:28:58 +0000 (17:28 +0000)
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
gcc/config/epiphany/epiphany.cc
gcc/config/epiphany/mode-switch-use.cc
gcc/config/i386/i386.cc
gcc/config/riscv/riscv.cc
gcc/config/sh/sh.cc
gcc/doc/tm.texi
gcc/mode-switching.cc
gcc/target.def

index 72c141c1a6d788b6dc9ef50b277af1666a7f446f..ef49a1e06a4aad81b81417f22b9fb304bec0f776 100644 (file)
@@ -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);
index a5460dbf97f5d1aa0dd0dd861922798e006f406b..60a9b49d8a487fa9722c77307c8da41f520beaeb 100644 (file)
@@ -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;
 
index 715306126580143e0757c01db50c6e11a7b84f25..183b9b7a3947074d99a82aa4b72b00ea3fc6dea2 100644 (file)
@@ -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)
index eec9b42396e0adfa20f57ca9c0f483da3faed8e2..a041e87d363d9dfc14c955e5334cc97dd0825ba8 100644 (file)
@@ -15060,7 +15060,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)
     {
index fa2d4d4b7795f13ece43b192b10c2c6ee32d2c3e..750eaf90ea2a81bccbe3c8c4f531b79d992048f0 100644 (file)
@@ -9426,7 +9426,7 @@ riscv_frm_mode_needed (rtx_insn *cur_insn, int code)
    prior to the execution of insn.  */
 
 static int
-riscv_mode_needed (int entity, rtx_insn *insn)
+riscv_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
 {
   int code = recog_memoized (insn);
 
index 294faf7c0c300442bf22dfa24c99d19ace618f24..c363490e85268a690815fa263dcb83d4d48d0040 100644 (file)
@@ -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);
@@ -12531,7 +12531,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;
 }
index 1a825c5004e8a1cfa748ad80705b7bcc3e4fdb97..144b3f88c37650dcc7923a814552f977106fc1c2 100644 (file)
@@ -10414,12 +10414,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})
index b8a887d81f71855ec3426d20ba8d78eed9f9352e..c5fe90ba449d16b4304f551ccc17b61be49113e6 100644 (file)
@@ -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))
@@ -610,7 +620,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)
index a70275b8abddde883f4345c075195f7841e66e7e..50bad184acafb722b8e22245f3bddcab20619b38 100644 (file)
@@ -7031,8 +7031,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,