Turn SECONDARY_MEMORY_NEEDED_MODE into a target hook
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 13 Sep 2017 17:04:08 +0000 (17:04 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 13 Sep 2017 17:04:08 +0000 (17:04 +0000)
This includes a change to LRA.  Previously the code was:

    if (sclass == NO_REGS && dclass == NO_REGS)
      return false;
  #ifdef SECONDARY_MEMORY_NEEDED
    if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
  #ifdef SECONDARY_MEMORY_NEEDED_MODE
        && ((sclass != NO_REGS && dclass != NO_REGS)
            || GET_MODE (src) != SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (src)))
  #endif
        )
      {
        *sec_mem_p = true;
        return false;
      }
  #endif

in which the positioning of the second ifdef meant that defining
SECONDARY_MEMORY_NEEDED_MODE to its default value was not a no-op:
without a definition, we would consider using secondary reloads for
mem<-reg and reg<-mem reloads even if the secondary memory has the
same mode as the original mem, while defining it would avoid this.
The latter behaviour seems correct.

The default is different for reload and LRA.  For LRA the default is
to use the original mode, while reload promotes smaller-than-word
integral modes to word mode:

  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
    mode = mode_for_size (BITS_PER_WORD,
                          GET_MODE_CLASS (mode), 0).require ();

Some of the ports that have switched to LRA seemed to have
SECONDARY_MEMORY_NEEDED_MDOEs based on the old reload definition,
and still referred to the reload.c:get_secondary_mem function in
the comments.  The patch just keeps them as-is.

2017-09-13  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* target.def (secondary_memory_needed_mode): New hook:
* targhooks.c (default_secondary_memory_needed_mode): Declare.
* targhooks.h (default_secondary_memory_needed_mode): New function.
* doc/tm.texi.in (SECONDARY_MEMORY_NEEDED_MODE): Replace with...
(TARGET_SECONDARY_MEMORY_NEEDED_MODE): ...this.
* doc/tm.texi: Regenerate.
* lra-constraints.c (check_and_process_move): Use
targetm.secondary_memory_needed_mode instead of
TARGET_SECONDARY_MEMORY_NEEDED_MODE.
(curr_insn_transform): Likewise.
* reload.c (get_secondary_mem): Likewise.
* config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
* config/alpha/alpha.c (alpha_secondary_memory_needed_mode): New
function.
(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
* config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
* config/i386/i386.c (ix86_secondary_memory_needed_mode): New function.
(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
* config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED_MODE):
Delete.
* config/powerpcspe/powerpcspe-protos.h
(rs6000_secondary_memory_needed_mode): Delete.
* config/powerpcspe/powerpcspe.c
(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
(rs6000_secondary_memory_needed_mode): Make static.
* config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
* config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_mode):
Delete.
* config/rs6000/rs6000.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
Redefine.
(rs6000_secondary_memory_needed_mode): Make static.
* config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
* config/s390/s390.c (s390_secondary_memory_needed_mode): New function.
(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
* config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
* config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
Redefine.
(sparc_secondary_memory_needed_mode): New function.
* system.h (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Poison.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r252455

23 files changed:
gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/powerpcspe/powerpcspe-protos.h
gcc/config/powerpcspe/powerpcspe.c
gcc/config/powerpcspe/powerpcspe.h
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/lra-constraints.c
gcc/reload.c
gcc/system.h
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h

index 1f941d4e8e87f915b501fe8799b198731636f31e..6b8f7f3fa1669580f6998fc8fdda034df5340cb8 100644 (file)
@@ -1,3 +1,47 @@
+2017-09-13  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * target.def (secondary_memory_needed_mode): New hook:
+       * targhooks.c (default_secondary_memory_needed_mode): Declare.
+       * targhooks.h (default_secondary_memory_needed_mode): New function.
+       * doc/tm.texi.in (SECONDARY_MEMORY_NEEDED_MODE): Replace with...
+       (TARGET_SECONDARY_MEMORY_NEEDED_MODE): ...this.
+       * doc/tm.texi: Regenerate.
+       * lra-constraints.c (check_and_process_move): Use
+       targetm.secondary_memory_needed_mode instead of
+       TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+       (curr_insn_transform): Likewise.
+       * reload.c (get_secondary_mem): Likewise.
+       * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+       * config/alpha/alpha.c (alpha_secondary_memory_needed_mode): New
+       function.
+       (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+       * config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+       * config/i386/i386.c (ix86_secondary_memory_needed_mode): New function.
+       (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+       * config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED_MODE):
+       Delete.
+       * config/powerpcspe/powerpcspe-protos.h
+       (rs6000_secondary_memory_needed_mode): Delete.
+       * config/powerpcspe/powerpcspe.c
+       (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+       (rs6000_secondary_memory_needed_mode): Make static.
+       * config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+       * config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_mode):
+       Delete.
+       * config/rs6000/rs6000.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
+       Redefine.
+       (rs6000_secondary_memory_needed_mode): Make static.
+       * config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+       * config/s390/s390.c (s390_secondary_memory_needed_mode): New function.
+       (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+       * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+       * config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
+       Redefine.
+       (sparc_secondary_memory_needed_mode): New function.
+       * system.h (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Poison.
+
 2017-09-13  Jackson Woodruff  <jackson.woodruff@arm.com>
 
        * config/aarch64/constraints.md (Umq): New constraint.
index ecc915d3c6c1903bc45277691d6a9648e956d20e..28fe4672b9c645bcc221b13c1efad56f501e56c7 100644 (file)
@@ -1688,6 +1688,21 @@ alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
 
   return NO_REGS;
 }
+
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.  If MODE is
+   floating-point, use it.  Otherwise, widen to a word like the default.
+   This is needed because we always store integers in FP registers in
+   quadword format.  This whole area is very tricky!  */
+
+static machine_mode
+alpha_secondary_memory_needed_mode (machine_mode mode)
+{
+  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+    return mode;
+  if (GET_MODE_SIZE (mode) >= 4)
+    return mode;
+  return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
+}
 \f
 /* Given SEQ, which is an INSN list, look for any MEMs in either
    a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
@@ -10062,6 +10077,8 @@ alpha_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode
 
 #undef TARGET_SCALAR_MODE_SUPPORTED_P
 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
index 56ba895bb19f3183c2c828c54bccbad28a24ae05..10f32b73db86738aaba656367a8af5e221ec9fc3 100644 (file)
@@ -486,16 +486,6 @@ enum reg_class {
  (! TARGET_FIX && (((CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS) \
                    || ((CLASS2) == FLOAT_REGS && (CLASS1) != FLOAT_REGS)))
 
-/* Specify the mode to be used for memory when a secondary memory
-   location is needed.  If MODE is floating-point, use it.  Otherwise,
-   widen to a word like the default.  This is needed because we always
-   store integers in FP registers in quadword format.  This whole
-   area is very tricky! */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)             \
-  (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE)                \
-   : GET_MODE_SIZE (MODE) >= 4 ? (MODE)                        \
-   : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ())
-
 /* Return the class of registers that cannot change mode from FROM to TO.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)              \
index edcc2d655b744efe4027990f0417236ddb8dda3b..a508f568eaf5704fc2bace0882c6819f0a4b3d9f 100644 (file)
@@ -41162,6 +41162,20 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
   return inline_secondary_memory_needed (class1, class2, mode, strict);
 }
 
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+   get_secondary_mem widens integral modes to BITS_PER_WORD.
+   There is no need to emit full 64 bit move on 64 bit targets
+   for integral modes that can be moved using 32 bit move.  */
+
+static machine_mode
+ix86_secondary_memory_needed_mode (machine_mode mode)
+{
+  if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
+    return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+  return mode;
+}
+
 /* Implement the TARGET_CLASS_MAX_NREGS hook.
 
    On the 80386, this is the size of MODE in words,
@@ -53206,6 +53220,8 @@ ix86_run_selftests (void)
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
 
 #undef TARGET_CLASS_MAX_NREGS
 #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
index a89782af13f25c6d93e517840059d3bb6b7113e9..09b8da564eca59dbb65ca6451e584f815ef73a7c 100644 (file)
@@ -1524,14 +1524,6 @@ enum reg_class
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
   ix86_secondary_memory_needed ((CLASS1), (CLASS2), (MODE), 1)
 
-/* Get_secondary_mem widens integral modes to BITS_PER_WORD.
-   There is no need to emit full 64 bit move on 64 bit targets
-   for integral modes that can be moved using 32 bit move.  */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)                     \
-  (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE)      \
-   ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require ()   \
-   : MODE)
-
 /* Return a class of registers that cannot change FROM mode to TO mode.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
index 20587ba17a685017d04f8c55d38cf9eeb4eab1f0..f3aa41bc516d4f0ec05b02b9a8a79a436d391ab1 100644 (file)
@@ -154,7 +154,6 @@ extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode);
 extern bool valid_sf_si_move (rtx, rtx, machine_mode);
 extern void rs6000_emit_move (rtx, rtx, machine_mode);
 extern rtx rs6000_secondary_memory_needed_rtx (machine_mode);
-extern machine_mode rs6000_secondary_memory_needed_mode (machine_mode);
 extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode,
                                                    int, int, int, int *);
 extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
index 77846763585be72bb89690e7f7df7d791458be72..9b8d68b8ea7c955d7611f8ec0174f5c76523f794 100644 (file)
@@ -1897,6 +1897,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode
 
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
@@ -21811,10 +21813,9 @@ rs6000_secondary_memory_needed_rtx (machine_mode mode)
   return ret;
 }
 
-/* Return the mode to be used for memory when a secondary memory
-   location is needed.  For SDmode values we need to use DDmode, in
-   all other cases we can use the same mode.  */
-machine_mode
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.  For SDmode values we
+   need to use DDmode, in all other cases we can use the same mode.  */
+static machine_mode
 rs6000_secondary_memory_needed_mode (machine_mode mode)
 {
   if (lra_in_progress && mode == SDmode)
index c4b6dc39feff0a03f9001235420b3de50a6ef19f..5d1a138f75825df53dd1e18f256a0e333aa79224 100644 (file)
@@ -1611,13 +1611,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
 #define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
   rs6000_secondary_memory_needed_rtx (MODE)
 
-/* Specify the mode to be used for memory when a secondary memory
-   location is needed.  For cpus that cannot load/store SDmode values
-   from the 64-bit FP registers without using a full 64-bit
-   load/store, we need a wider mode.  */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)             \
-  rs6000_secondary_memory_needed_mode (MODE)
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.
 
index f9be5d3ff9361a5647349b7d26622a4d0a7b3103..b21652b40b49cc2fef05a85b243d31dbca9b4c49 100644 (file)
@@ -155,7 +155,6 @@ extern void rs6000_emit_le_vsx_permute (rtx, rtx, machine_mode);
 extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode);
 extern bool valid_sf_si_move (rtx, rtx, machine_mode);
 extern void rs6000_emit_move (rtx, rtx, machine_mode);
-extern machine_mode rs6000_secondary_memory_needed_mode (machine_mode);
 extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode,
                                                    int, int, int, int *);
 extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
index 13383712046d6a93b74315d97b3e225d01d731d2..a4a89d03dfead74502aa56636adad597db481a8b 100644 (file)
@@ -1876,6 +1876,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode
 
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
@@ -19242,10 +19244,9 @@ mems_ok_for_quad_peep (rtx mem1, rtx mem2)
   return 1;
 }
 \f
-/* Return the mode to be used for memory when a secondary memory
-   location is needed.  For SDmode values we need to use DDmode, in
-   all other cases we can use the same mode.  */
-machine_mode
+/* Implement TARGET_SECONDARY_RELOAD_NEEDED_MODE.  For SDmode values we
+   need to use DDmode, in all other cases we can use the same mode.  */
+static machine_mode
 rs6000_secondary_memory_needed_mode (machine_mode mode)
 {
   if (lra_in_progress && mode == SDmode)
index 7ac6e3b3d08ab9088ab487e178411038cfc42ba1..1a7ce96202048451d1a4961cee8926fc68e89a8e 100644 (file)
@@ -1514,13 +1514,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
 #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE)                    \
   rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, MODE)
 
-/* Specify the mode to be used for memory when a secondary memory
-   location is needed.  For cpus that cannot load/store SDmode values
-   from the 64-bit FP registers without using a full 64-bit
-   load/store, we need a wider mode.  */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)             \
-  rs6000_secondary_memory_needed_mode (MODE)
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.
 
index 46d6c32bd9c40b02736299a8a60e6093f90c29af..1319f680eb13d0d1b8f27b919a27310c2b984995 100644 (file)
@@ -4409,6 +4409,19 @@ s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
   return NO_REGS;
 }
 
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+   get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
+   because the movsi and movsf patterns don't handle r/f moves.  */
+
+static machine_mode
+s390_secondary_memory_needed_mode (machine_mode mode)
+{
+  if (GET_MODE_BITSIZE (mode) < 32)
+    return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+  return mode;
+}
+
 /* Generate code to load SRC, which is PLUS that is not a
    legitimate operand for the LA instruction, into TARGET.
    SCRATCH may be used as scratch register.  */
@@ -15959,6 +15972,8 @@ s390_asan_shadow_offset (void)
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE s390_secondary_memory_needed_mode
 
 #undef TARGET_LIBGCC_CMP_RETURN_MODE
 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
index 0682fb668bced796b3c1b43489e38c663fb9fd16..b4a23c3aa8cd1b416d2a4cf072cde362dd3927e0 100644 (file)
@@ -599,13 +599,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
    && (!TARGET_VX || (SCALAR_FLOAT_MODE_P (MODE)                       \
                          && GET_MODE_SIZE (MODE) > 8)))
 
-/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
-   because the movsi and movsf patterns don't handle r/f moves.  */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)                     \
- (GET_MODE_BITSIZE (MODE) < 32                                 \
-  ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require ()    \
-  : (MODE))
-
 
 /* Stack layout and calling conventions.  */
 
index 9a7e46794b289e4c0d01415f35435c9fe48616fe..469b03d2f8883464890579e82656ec061b9a568a 100644 (file)
@@ -672,6 +672,7 @@ static void sparc_print_operand_address (FILE *, machine_mode, rtx);
 static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
                                           machine_mode,
                                           secondary_reload_info *);
+static machine_mode sparc_secondary_memory_needed_mode (machine_mode);
 static scalar_int_mode sparc_cstore_mode (enum insn_code icode);
 static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
 static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *);
@@ -859,6 +860,8 @@ char sparc_hard_reg_printed[8];
 
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD sparc_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE sparc_secondary_memory_needed_mode
 
 #undef TARGET_CONDITIONAL_REGISTER_USAGE
 #define TARGET_CONDITIONAL_REGISTER_USAGE sparc_conditional_register_usage
@@ -13050,6 +13053,30 @@ sparc_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
   return NO_REGS;
 }
 
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+   get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
+   because the movsi and movsf patterns don't handle r/f moves.
+   For v8 we copy the default definition.  */
+
+static machine_mode
+sparc_secondary_memory_needed_mode (machine_mode mode)
+{
+  if (TARGET_ARCH64)
+    {
+      if (GET_MODE_BITSIZE (mode) < 32)
+       return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+      return mode;
+    }
+  else
+    {
+      if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
+       return mode_for_size (BITS_PER_WORD,
+                             GET_MODE_CLASS (mode), 0).require ();
+      return mode;
+    }
+}
+
 /* Emit code to conditionally move either OPERANDS[2] or OPERANDS[3] into
    OPERANDS[0] in MODE.  OPERANDS[1] is the operator of the condition.  */
 
index e037897d642e373474817bf0b18479b7bbccb817..51bc3183ed5e36a341d06a77aa834942a38fed24 100644 (file)
@@ -1055,18 +1055,6 @@ extern char leaf_reg_remap[];
        || GET_MODE_SIZE (MODE) > 8 \
        || GET_MODE_SIZE (MODE) < 4))
 
-/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
-   because the movsi and movsf patterns don't handle r/f moves.
-   For v8 we copy the default definition.  */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE)                                \
-  (TARGET_ARCH64                                                          \
-   ? (GET_MODE_BITSIZE (MODE) < 32                                        \
-      ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require ()                   \
-      : MODE)                                                             \
-   : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD                             \
-      ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \
-      : MODE))
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 /* On SPARC, this is the size of MODE in words.  */
index 98e6015e378df019d9a4f9232f1e56c10c44482b..5e90208f5eba42900791078bf3c89be3d0903462 100644 (file)
@@ -2747,29 +2747,27 @@ Do not define this macro if you do not define
 @code{SECONDARY_MEMORY_NEEDED}.
 @end defmac
 
-@defmac SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
-When the compiler needs a secondary memory location to copy between two
-registers of mode @var{mode}, it normally allocates sufficient memory to
-hold a quantity of @code{BITS_PER_WORD} bits and performs the store and
-load operations in a mode that many bits wide and whose class is the
-same as that of @var{mode}.
-
-This is right thing to do on most machines because it ensures that all
-bits of the register are copied and prevents accesses to the registers
-in a narrower mode, which some machines prohibit for floating-point
-registers.
+@deftypefn {Target Hook} machine_mode TARGET_SECONDARY_MEMORY_NEEDED_MODE (machine_mode @var{mode})
+If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory
+when moving between two particular registers of mode @var{mode},
+this hook specifies the mode that the memory should have.
+
+The default depends on @code{TARGET_LRA_P}.  Without LRA, the default
+is to use a word-sized mode for integral modes that are smaller than a
+a word.  This is right thing to do on most machines because it ensures
+that all bits of the register are copied and prevents accesses to the
+registers in a narrower mode, which some machines prohibit for
+floating-point registers.
 
 However, this default behavior is not correct on some machines, such as
 the DEC Alpha, that store short integers in floating-point registers
 differently than in integer registers.  On those machines, the default
-widening will not work correctly and you must define this macro to
-suppress that widening in some cases.  See the file @file{alpha.h} for
+widening will not work correctly and you must define this hook to
+suppress that widening in some cases.  See the file @file{alpha.c} for
 details.
 
-Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED} or if widening @var{mode} to a mode that
-is @code{BITS_PER_WORD} bits wide is correct for your machine.
-@end defmac
+With LRA, the default is to use @var{mode} unmodified.
+@end deftypefn
 
 @deftypefn {Target Hook} bool TARGET_CLASS_LIKELY_SPILLED_P (reg_class_t @var{rclass})
 A target hook which returns @code{true} if pseudos that have been assigned
index acf47e0d812b8d5a44260cbf839915e7a31cde38..1919176d866a3401347f875582701774df9026fc 100644 (file)
@@ -2324,29 +2324,7 @@ Do not define this macro if you do not define
 @code{SECONDARY_MEMORY_NEEDED}.
 @end defmac
 
-@defmac SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
-When the compiler needs a secondary memory location to copy between two
-registers of mode @var{mode}, it normally allocates sufficient memory to
-hold a quantity of @code{BITS_PER_WORD} bits and performs the store and
-load operations in a mode that many bits wide and whose class is the
-same as that of @var{mode}.
-
-This is right thing to do on most machines because it ensures that all
-bits of the register are copied and prevents accesses to the registers
-in a narrower mode, which some machines prohibit for floating-point
-registers.
-
-However, this default behavior is not correct on some machines, such as
-the DEC Alpha, that store short integers in floating-point registers
-differently than in integer registers.  On those machines, the default
-widening will not work correctly and you must define this macro to
-suppress that widening in some cases.  See the file @file{alpha.h} for
-details.
-
-Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED} or if widening @var{mode} to a mode that
-is @code{BITS_PER_WORD} bits wide is correct for your machine.
-@end defmac
+@hook TARGET_SECONDARY_MEMORY_NEEDED_MODE
 
 @hook TARGET_CLASS_LIKELY_SPILLED_P
 
index 4859c584121d5aaf820ef54ec90f748c488944b1..84be6c3fdcafd9bd5a17b5b8cd74c01d40f66f8b 100644 (file)
@@ -1203,11 +1203,9 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
     return false;
 #ifdef SECONDARY_MEMORY_NEEDED
   if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
       && ((sclass != NO_REGS && dclass != NO_REGS)
-         || GET_MODE (src) != SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (src)))
-#endif
-      )
+         || (GET_MODE (src)
+             != targetm.secondary_memory_needed_mode (GET_MODE (src)))))
     {
       *sec_mem_p = true;
       return false;
@@ -3940,11 +3938,7 @@ curr_insn_transform (bool check_only_p)
                  && curr_static_id->operand[in].type == OP_IN);
       rld = partial_subreg_p (GET_MODE (src), GET_MODE (dest)) ? src : dest;
       rld_mode = GET_MODE (rld);
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
-      sec_mode = SECONDARY_MEMORY_NEEDED_MODE (rld_mode);
-#else
-      sec_mode = rld_mode;
-#endif
+      sec_mode = targetm.secondary_memory_needed_mode (rld_mode);
       new_reg = lra_create_new_reg (sec_mode, NULL_RTX,
                                    NO_REGS, "secondary");
       /* If the mode is changed, it should be wider.  */
index a5dd47ccab672670b54293eb22a9150261f8e80c..d0061e5b27087a2c49dc697c4599091727f9a46c 100644 (file)
@@ -574,13 +574,7 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSED, machine_mode mode,
      locations do not support short load and stores from all registers
      (e.g., FP registers).  */
 
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
-  mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
-#else
-  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
-    mode = mode_for_size (BITS_PER_WORD,
-                         GET_MODE_CLASS (mode), 0).require ();
-#endif
+  mode = targetm.secondary_memory_needed_mode (mode);
 
   /* If we already have made a MEM for this operand in MODE, return it.  */
   if (secondary_memlocs_elim[(int) mode][opnum] != 0)
index 00c3e3f9b89f1c833b2a6a13deb0995adeb6608c..7543339978e1f4872c1f6770da885b312cc23f3f 100644 (file)
@@ -913,7 +913,7 @@ extern void fancy_abort (const char *, int, const char *)
        STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD                        \
        HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK               \
        MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS      \
-       HARD_REGNO_NREGS
+       HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE
 
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
index 6462c942b4d567b7331203fa51b42e7e4e60b434..7abb74e79c0352c885da3d1aefe2eb416d28097d 100644 (file)
@@ -5265,6 +5265,30 @@ forwarding logic, you can set @code{sri->extra_cost} to a negative amount.",
   secondary_reload_info *sri),
  default_secondary_reload)
 
+DEFHOOK
+(secondary_memory_needed_mode,
+ "If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory\n\
+when moving between two particular registers of mode @var{mode},\n\
+this hook specifies the mode that the memory should have.\n\
+\n\
+The default depends on @code{TARGET_LRA_P}.  Without LRA, the default\n\
+is to use a word-sized mode for integral modes that are smaller than a\n\
+a word.  This is right thing to do on most machines because it ensures\n\
+that all bits of the register are copied and prevents accesses to the\n\
+registers in a narrower mode, which some machines prohibit for\n\
+floating-point registers.\n\
+\n\
+However, this default behavior is not correct on some machines, such as\n\
+the DEC Alpha, that store short integers in floating-point registers\n\
+differently than in integer registers.  On those machines, the default\n\
+widening will not work correctly and you must define this hook to\n\
+suppress that widening in some cases.  See the file @file{alpha.c} for\n\
+details.\n\
+\n\
+With LRA, the default is to use @var{mode} unmodified.",
+ machine_mode, (machine_mode mode),
+ default_secondary_memory_needed_mode)
+
 /* Given an rtx X being reloaded into a reg required to be in class CLASS,
    return the class of reg to actually use.  */
 DEFHOOK
index d2b70827d72a537f06b8fbbd7cd350468679b99a..98e553c0fce799fe531dbf6bdec43e5123f47eef 100644 (file)
@@ -1129,6 +1129,18 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
   return rclass;
 }
 
+/* The default implementation of TARGET_SECONDARY_MEMORY_NEEDED_MODE.  */
+
+machine_mode
+default_secondary_memory_needed_mode (machine_mode mode)
+{
+  if (!targetm.lra_p ()
+      && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+      && INTEGRAL_MODE_P (mode))
+    return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
+  return mode;
+}
+
 /* By default, if flag_pic is true, then neither local nor global relocs
    should be placed in readonly memory.  */
 
index a0bd4aa3e24c05b409381f01989386f490e8bc52..3d03215f7b7f226df619827e9f811c18beba9237 100644 (file)
@@ -159,6 +159,7 @@ extern bool default_different_addr_displacement_p (void);
 extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
                                             machine_mode,
                                             secondary_reload_info *);
+extern machine_mode default_secondary_memory_needed_mode (machine_mode);
 extern void default_target_option_override (void);
 extern void hook_void_bitmap (bitmap);
 extern int default_reloc_rw_mask (void);