Pass an ABI to choose_hard_reg_mode
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 30 Sep 2019 16:20:04 +0000 (16:20 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 30 Sep 2019 16:20:04 +0000 (16:20 +0000)
choose_hard_reg_mode previously took a boolean saying whether the
mode needed to be call-preserved.  This patch replaces it with an
optional ABI pointer instead, so that the function can use that
to test whether a value is call-saved.

default_dwarf_frame_reg_mode uses eh_edge_abi because that's the
ABI that matters for unwinding.  Targets need to override the hook
if they want something different.

2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* rtl.h (predefined_function_abi): Declare.
(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
instead of a boolean call_save flag.
* config/gcn/gcn.c (gcn_hard_regno_caller_save_mode): Update call
accordingly.
* config/i386/i386.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/mips/mips.c (mips_hard_regno_caller_save_mode): Likewise.
* config/msp430/msp430.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/sh/sh.c (sh_hard_regno_caller_save_mode): Likewise.
* reginfo.c (init_reg_modes_target): Likewise.
(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
instead of a boolean call_save flag.
* targhooks.c: Include function-abi.h.
(default_dwarf_frame_reg_mode): Update call to choose_hard_reg_mode,
using eh_edge_abi to choose the mode.

From-SVN: r276312

gcc/ChangeLog
gcc/config/gcn/gcn.c
gcc/config/i386/i386.h
gcc/config/ia64/ia64.h
gcc/config/mips/mips.c
gcc/config/msp430/msp430.h
gcc/config/rs6000/rs6000.h
gcc/config/sh/sh.c
gcc/reginfo.c
gcc/rtl.h
gcc/targhooks.c

index 59bfeb2..86caf6e 100644 (file)
@@ -1,5 +1,25 @@
 2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>
 
+       * rtl.h (predefined_function_abi): Declare.
+       (choose_hard_reg_mode): Take a pointer to a predefined_function_abi
+       instead of a boolean call_save flag.
+       * config/gcn/gcn.c (gcn_hard_regno_caller_save_mode): Update call
+       accordingly.
+       * config/i386/i386.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
+       * config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
+       * config/mips/mips.c (mips_hard_regno_caller_save_mode): Likewise.
+       * config/msp430/msp430.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
+       * config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
+       * config/sh/sh.c (sh_hard_regno_caller_save_mode): Likewise.
+       * reginfo.c (init_reg_modes_target): Likewise.
+       (choose_hard_reg_mode): Take a pointer to a predefined_function_abi
+       instead of a boolean call_save flag.
+       * targhooks.c: Include function-abi.h.
+       (default_dwarf_frame_reg_mode): Update call to choose_hard_reg_mode,
+       using eh_edge_abi to choose the mode.
+
+2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>
+
        * target.def (hard_regno_call_part_clobbered): Take an ABI
        identifier instead of an rtx_insn.
        * doc/tm.texi: Regenerate.
index 50ae8e1..b5f09da 100644 (file)
@@ -3017,7 +3017,7 @@ machine_mode
 gcn_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
                                 machine_mode regmode)
 {
-  machine_mode result = choose_hard_reg_mode (regno, nregs, false);
+  machine_mode result = choose_hard_reg_mode (regno, nregs, NULL);
 
   if (VECTOR_MODE_P (result) && !VECTOR_MODE_P (regmode))
     result = (nregs == 1 ? SImode : DImode);
index 885846e..9fe1f45 100644 (file)
@@ -1258,7 +1258,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE)                        \
   (CC_REGNO_P (REGNO) ? VOIDmode                                       \
    : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode                     \
-   : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \
+   : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), NULL)        \
    : (MODE) == HImode && !((GENERAL_REGNO_P (REGNO)                    \
                            && TARGET_PARTIAL_REG_STALL)                \
                           || MASK_REGNO_P (REGNO)) ? SImode            \
index d9d78fd..fc985b4 100644 (file)
@@ -562,7 +562,7 @@ while (0)
 
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
   ((FR_REGNO_P (REGNO) && (NREGS) == 1) ? RFmode        \
-   : choose_hard_reg_mode ((REGNO), (NREGS), false))
+   : choose_hard_reg_mode ((REGNO), (NREGS), NULL))
 \f
 /* Handling Leaf Functions */
 
index 91dd94b..648d95f 100644 (file)
@@ -22174,7 +22174,7 @@ mips_hard_regno_caller_save_mode (unsigned int regno,
   /* For performance, avoid saving/restoring upper parts of a register
      by returning MODE as save mode when the mode is known.  */
   if (mode == VOIDmode)
-    return choose_hard_reg_mode (regno, nregs, false);
+    return choose_hard_reg_mode (regno, nregs, NULL);
   else
     return mode;
 }
index 36b715d..3449bd4 100644 (file)
@@ -467,7 +467,7 @@ typedef struct
    when spilling hard registers when they may contain PSImode values.  */
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \
   ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode \
-   : choose_hard_reg_mode ((REGNO), (NREGS), false))
+   : choose_hard_reg_mode ((REGNO), (NREGS), NULL))
 
 #define ACCUMULATE_OUTGOING_ARGS 1
 
index 0156448..27373c5 100644 (file)
@@ -1038,7 +1038,7 @@ enum data_align { align_abi, align_opt, align_both };
    ? DFmode                                                            \
    : (MODE) == TDmode && FP_REGNO_P (REGNO)                            \
    ? DImode                                                            \
-   : choose_hard_reg_mode ((REGNO), (NREGS), false))
+   : choose_hard_reg_mode ((REGNO), (NREGS), NULL))
 
 #define VSX_VECTOR_MODE(MODE)          \
         ((MODE) == V4SFmode            \
index 34c4c8f..9917f2b 100644 (file)
@@ -10637,7 +10637,7 @@ sh_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
              && ((regno - FIRST_FP_REG) & 1) == 0)))
     return mode;
 
-  return choose_hard_reg_mode (regno, nregs, false);
+  return choose_hard_reg_mode (regno, nregs, NULL);
 }
 
 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
index f084c0e..265157f 100644 (file)
@@ -442,7 +442,7 @@ init_reg_modes_target (void)
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
-      reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
+      reg_raw_mode[i] = choose_hard_reg_mode (i, 1, NULL);
 
       /* If we couldn't find a valid mode, just use the previous mode
         if it is suitable, otherwise fall back on word_mode.  */
@@ -550,10 +550,11 @@ memory_move_secondary_cost (machine_mode mode, reg_class_t rclass,
 
 /* Return a machine mode that is legitimate for hard reg REGNO and large
    enough to save nregs.  If we can't find one, return VOIDmode.
-   If CALL_SAVED is true, only consider modes that are call saved.  */
+   If ABI is nonnull, only consider modes that are preserved across
+   calls that use ABI.  */
 machine_mode
 choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
-                     unsigned int nregs, bool call_saved)
+                     unsigned int nregs, const predefined_function_abi *abi)
 {
   unsigned int /* machine_mode */ m;
   machine_mode found_mode = VOIDmode, mode;
@@ -567,32 +568,28 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
   FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     if (hard_regno_nregs (regno, mode) == nregs
        && targetm.hard_regno_mode_ok (regno, mode)
-       && (!call_saved
-           || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
+       && (!abi || !abi->clobbers_reg_p (mode, regno))
        && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     if (hard_regno_nregs (regno, mode) == nregs
        && targetm.hard_regno_mode_ok (regno, mode)
-       && (!call_saved
-           || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
+       && (!abi || !abi->clobbers_reg_p (mode, regno))
        && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
     if (hard_regno_nregs (regno, mode) == nregs
        && targetm.hard_regno_mode_ok (regno, mode)
-       && (!call_saved
-           || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
+       && (!abi || !abi->clobbers_reg_p (mode, regno))
        && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
     if (hard_regno_nregs (regno, mode) == nregs
        && targetm.hard_regno_mode_ok (regno, mode)
-       && (!call_saved
-           || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
+       && (!abi || !abi->clobbers_reg_p (mode, regno))
        && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
       found_mode = mode;
 
@@ -605,8 +602,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
       mode = (machine_mode) m;
       if (hard_regno_nregs (regno, mode) == nregs
          && targetm.hard_regno_mode_ok (regno, mode)
-         && (!call_saved
-             || !targetm.hard_regno_call_part_clobbered (0, regno, mode)))
+         && (!abi || !abi->clobbers_reg_p (mode, regno)))
        return mode;
     }
 
index d798562..554608c 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -36,6 +36,8 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "hard-reg-set.h"
 
+class predefined_function_abi;
+
 /* Value used by some passes to "recognize" noop moves as valid
  instructions.  */
 #define NOOP_MOVE_INSN_CODE    INT_MAX
@@ -3410,7 +3412,8 @@ extern bool val_signbit_known_clear_p (machine_mode,
                                       unsigned HOST_WIDE_INT);
 
 /* In reginfo.c  */
-extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int, bool);
+extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
+                                         const predefined_function_abi *);
 extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
 
 /* In emit-rtl.c  */
index 6105137..5445038 100644 (file)
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "real.h"
 #include "langhooks.h"
 #include "sbitmap.h"
+#include "function-abi.h"
 
 bool
 default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
@@ -1928,8 +1929,9 @@ default_dwarf_frame_reg_mode (int regno)
 {
   machine_mode save_mode = reg_raw_mode[regno];
 
-  if (targetm.hard_regno_call_part_clobbered (0, regno, save_mode))
-    save_mode = choose_hard_reg_mode (regno, 1, true);
+  if (targetm.hard_regno_call_part_clobbered (eh_edge_abi.id (),
+                                             regno, save_mode))
+    save_mode = choose_hard_reg_mode (regno, 1, &eh_edge_abi);
   return save_mode;
 }