]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tm.texi (defmac SMALL_REGISTER_CLASSES): Remove.
authorSteven Bosscher <steven@gcc.gnu.org>
Mon, 3 May 2010 17:47:47 +0000 (17:47 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Mon, 3 May 2010 17:47:47 +0000 (17:47 +0000)
* doc/tm.texi (defmac SMALL_REGISTER_CLASSES): Remove.
(TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P): Add documentation,
based on the above, for new target hook.

* hooks.c (hook_bool_mode_true): New generic hook.
* hooks.h (hook_bool_mode_true): Add prototype.

* target.h (struct gcc_target): Add small_register_classes_for_mode_p
target hook.
* target-def.h (TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P): New default
target hook, set to hook_bool_mode_false.
* regs.h: Remove default definition of SMALL_REGISTER_CLASSES.
* reload.c (push_secondary_reload): Replace SMALL_REGISTER_CLASSES
with targetm.small_register_classes_for_mode_p.
(find_reusable_reload): Likewise.
(combine_reloads): Likewise.
* reload1.c (reload_as_needed): Likewise.
* cse.c (approx_reg_cost_1, hash_rtx_cb): Likewise.
* ifcvt.c (noce_process_if_block, check_cond_move_block,
dead_or_predicable): Likewise.
* regmove.c (optimize_reg_copy_1): Likewise.
* calls.c (prepare_call_address): Likewise.
(precompute_register_parameters): Likewise.

* config/sh/sh.h: Replace SMALL_REGISTER_CLASSES with new target
hook definition.
* config/sh/sh.c (sh_small_register_classes_for_mode_p): Add
implementation of the hook that considers all register classes
small except for SH64.
(sh_override_options): Use the new hook.
* config/sh/sh-protos.h (sh_small_register_classes_for_mode_p):
Add prototype.

* config/arm/arm.h: Replace SMALL_REGISTER_CLASSES with new target
hook definition.
* config/arm/arm.c (arm_small_register_classes_for_mode_p): Add
implementation of the hook that considers all register classes
small for THUMB1.
* config/arm/arm-protos.h (arm_small_register_classes_for_mode_p):
Add prototype.

* config/mips/mips.h: Replace SMALL_REGISTER_CLASSES with new target
hook definition.
* config/mips/mips.c (mips_small_register_classes_for_mode_p): Add
implementation of the hook that considers all register classes
small for MIPS16.
* config/mips/mips-protos.h (mips_small_register_classes_for_mode_p):
Add prototype.

* config/i386/i386.h: Replace SMALL_REGISTER_CLASSES with new target
hook definition.
* config/m32c/m32c.h: Likewise.
* config/pdp11/pdp11.h: Likewise.
* config/avr/avr.h: Likewise.
* config/xtensa/xtensa.h: Likewise.
* config/m68hc11/m68hc11.h: Likewise.
* config/mn10300/mn10300.h: Likewise.
* config/mcore/mcore.h: Likewise.
* config/h8300/h8300.h: Likewise.
* config/bfin/bfin.h: Likewise.

* config/iq2000/iq2000.h: Remove SMALL_REGISTER_CLASSES definition.
* config/rx/rx.h: Remove SMALL_REGISTER_CLASSES definition.

From-SVN: r158997

37 files changed:
gcc/ChangeLog
gcc/calls.c
gcc/cfgrtl.c
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/avr/avr.h
gcc/config/bfin/bfin.h
gcc/config/h8300/h8300.h
gcc/config/i386/i386.h
gcc/config/iq2000/iq2000.h
gcc/config/m32c/m32c.h
gcc/config/m68hc11/m68hc11.h
gcc/config/mcore/mcore.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mn10300/mn10300.h
gcc/config/pdp11/pdp11.h
gcc/config/rx/rx.h
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/xtensa/xtensa.h
gcc/cse.c
gcc/doc/tm.texi
gcc/gcse.c
gcc/hooks.c
gcc/hooks.h
gcc/ifcvt.c
gcc/regmove.c
gcc/regs.h
gcc/reload.c
gcc/reload1.c
gcc/sched-deps.c
gcc/target-def.h
gcc/target.h

index 485dfbe4e5eb37ca3094a7f75ffb49a2f4cf1dd6..727f89724ce48d7e602a8fce2843b2bc0110f79f 100644 (file)
@@ -1,3 +1,69 @@
+2010-05-03  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * doc/tm.texi (defmac SMALL_REGISTER_CLASSES): Remove.
+       (TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P): Add documentation,
+       based on the above, for new target hook.
+
+       * hooks.c (hook_bool_mode_true): New generic hook.
+       * hooks.h (hook_bool_mode_true): Add prototype.
+
+       * target.h (struct gcc_target): Add small_register_classes_for_mode_p
+       target hook.
+       * target-def.h (TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P): New default
+       target hook, set to hook_bool_mode_false.
+       * regs.h: Remove default definition of SMALL_REGISTER_CLASSES.
+       * reload.c (push_secondary_reload): Replace SMALL_REGISTER_CLASSES
+       with targetm.small_register_classes_for_mode_p.
+       (find_reusable_reload): Likewise.
+       (combine_reloads): Likewise.
+       * reload1.c (reload_as_needed): Likewise.
+       * cse.c (approx_reg_cost_1, hash_rtx_cb): Likewise.
+       * ifcvt.c (noce_process_if_block, check_cond_move_block,
+       dead_or_predicable): Likewise.
+       * regmove.c (optimize_reg_copy_1): Likewise.
+       * calls.c (prepare_call_address): Likewise.
+       (precompute_register_parameters): Likewise.
+
+       * config/sh/sh.h: Replace SMALL_REGISTER_CLASSES with new target
+       hook definition.
+       * config/sh/sh.c (sh_small_register_classes_for_mode_p): Add
+       implementation of the hook that considers all register classes
+       small except for SH64.
+       (sh_override_options): Use the new hook.
+       * config/sh/sh-protos.h (sh_small_register_classes_for_mode_p):
+       Add prototype.
+
+       * config/arm/arm.h: Replace SMALL_REGISTER_CLASSES with new target
+       hook definition.
+       * config/arm/arm.c (arm_small_register_classes_for_mode_p): Add
+       implementation of the hook that considers all register classes
+       small for THUMB1.
+       * config/arm/arm-protos.h (arm_small_register_classes_for_mode_p):
+       Add prototype.
+
+       * config/mips/mips.h: Replace SMALL_REGISTER_CLASSES with new target
+       hook definition.
+       * config/mips/mips.c (mips_small_register_classes_for_mode_p): Add
+       implementation of the hook that considers all register classes
+       small for MIPS16.
+       * config/mips/mips-protos.h (mips_small_register_classes_for_mode_p):
+       Add prototype.
+
+       * config/i386/i386.h: Replace SMALL_REGISTER_CLASSES with new target
+       hook definition.
+       * config/m32c/m32c.h: Likewise.
+       * config/pdp11/pdp11.h: Likewise.
+       * config/avr/avr.h: Likewise.
+       * config/xtensa/xtensa.h: Likewise.
+       * config/m68hc11/m68hc11.h: Likewise.
+       * config/mn10300/mn10300.h: Likewise.
+       * config/mcore/mcore.h: Likewise.
+       * config/h8300/h8300.h: Likewise.
+       * config/bfin/bfin.h: Likewise.
+
+       * config/iq2000/iq2000.h: Remove SMALL_REGISTER_CLASSES definition.
+       * config/rx/rx.h: Remove SMALL_REGISTER_CLASSES definition.
+
 2010-05-03  Anatoly Sokolov  <aesok@post.ru>
 
        * double-int.h (tree_to_double_int): Remove macro.
index 496ec602bc614d8524bb43d702e0d7bcfd1f3429..9c51f1a5a74e9b66f58c856e0455e9258dabea78 100644 (file)
@@ -175,7 +175,8 @@ prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value,
   if (GET_CODE (funexp) != SYMBOL_REF)
     /* If we are using registers for parameters, force the
        function address into a register now.  */
-    funexp = ((SMALL_REGISTER_CLASSES && reg_parm_seen)
+    funexp = ((reg_parm_seen
+              && targetm.small_register_classes_for_mode_p (FUNCTION_MODE))
              ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
              : memory_address (FUNCTION_MODE, funexp));
   else if (! sibcallp)
@@ -711,7 +712,8 @@ precompute_register_parameters (int num_actuals, struct arg_data *args,
                 && args[i].mode != BLKmode
                 && rtx_cost (args[i].value, SET, optimize_insn_for_speed_p ())
                    > COSTS_N_INSNS (1)
-                && ((SMALL_REGISTER_CLASSES && *reg_parm_seen)
+                && ((*reg_parm_seen
+                     && targetm.small_register_classes_for_mode_p (args[i].mode))
                     || optimize))
          args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
       }
index 13e0e5c40d6c5242b9440640dde1f49659d718d4..7fb1873f53b66c8f589be59b7fe5099b20e9f94f 100644 (file)
@@ -3123,10 +3123,10 @@ insert_insn_end_bb_new (rtx pat, basic_block bb)
            && (!single_succ_p (bb)
                || single_succ_edge (bb)->flags & EDGE_ABNORMAL))
     {
-      /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
-         we search backward and place the instructions before the first
-         parameter is loaded.  Do this for everyone for consistency and a
-         presumption that we'll get better code elsewhere as well.  */
+      /* Keeping in mind targets with small register classes and parameters
+         in registers, we search backward and place the instructions before
+        the first parameter is loaded.  Do this for everyone for consistency
+        and a presumption that we'll get better code elsewhere as well.  */
 
       /* Since different machines initialize their parameter registers
          in different orders, assume nothing.  Collect the set of all
index 5a42a259df5bf63d791f14c03ba9e1bf26a00a07..2933201a1ebbce2ced1fb478de8b4574b5fc7c00 100644 (file)
@@ -45,6 +45,7 @@ extern void arm_output_fn_unwind (FILE *, bool);
 
 #ifdef RTX_CODE
 extern bool arm_vector_mode_supported_p (enum machine_mode);
+extern bool arm_small_register_classes_for_mode_p (enum machine_mode);
 extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
 extern int const_ok_for_arm (HOST_WIDE_INT);
 extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
index 884a1bdace937d1bcf12687a9eb962583cba4f55..7f3cdfa239fff7b71f97c29fd4095e985d5963c7 100644 (file)
@@ -20944,6 +20944,13 @@ arm_vector_mode_supported_p (enum machine_mode mode)
   return false;
 }
 
+/* Implements target hook small_register_classes_for_mode_p.  */
+bool
+arm_small_register_classes_for_mode_p (enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return TARGET_THUMB1;
+}
+
 /* Implement TARGET_SHIFT_TRUNCATION_MASK.  SImode shifts use normal
    ARM insns and therefore guarantee that the shift count is modulo 256.
    DImode shifts (those implemented by lib1funcs.asm or by optabs.c)
index ca46db1cca2659b39d3de91afbe4ba74cc30c09c..b672535c1c84637df505e854ac4292009786a1d9 100644 (file)
@@ -1267,11 +1267,12 @@ enum reg_class
    instead of BASE_REGS.  */
 #define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS
 
-/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
+/* When this hook returns true for MODE, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
    registers.  */
-#define SMALL_REGISTER_CLASSES   TARGET_THUMB1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  arm_small_register_classes_for_mode_p 
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
index 67e0c8f04f1d30ac97d9787573e284d62f754b29..398b412dd911a5821a337c14a31f73b8e12ad6c4 100644 (file)
@@ -333,7 +333,7 @@ enum reg_class {
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS) preferred_reload_class(X,CLASS)
 
-#define SMALL_REGISTER_CLASSES 1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define CLASS_LIKELY_SPILLED_P(c) class_likely_spilled_p(c)
 
index 365680ee9fa095c5a6a927b05963ce09ea3ee947..a1bd556003e98f7ba83ff2d68932681d9de5260b 100644 (file)
@@ -756,10 +756,11 @@ enum reg_class
     MOST_REGS, AREGS, CCREGS, LIM_REG_CLASSES          \
 }
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers. */
-#define SMALL_REGISTER_CLASSES 1
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define CLASS_LIKELY_SPILLED_P(CLASS) \
     ((CLASS) == PREGS_CLOBBERED \
index f77dfa31407c850af7ca6ca94f4a9672f17d8b07..1ce1585544efc1fdafc67bbad177bcfb16f264d4 100644 (file)
@@ -608,11 +608,11 @@ enum reg_class {
 
 #define FUNCTION_ARG_REGNO_P(N) (TARGET_QUICKCALL ? N < 3 : 0)
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers.  */
-
-#define SMALL_REGISTER_CLASSES 1
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 \f
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
index ebe32388d804d72cdf8d50214099b1fe12c6f27f..18e3eb3b45ad6f75e99515711aa4131b827fb631 100644 (file)
@@ -1296,11 +1296,11 @@ enum reg_class
 
 #define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers.  */
-
-#define SMALL_REGISTER_CLASSES 1
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define QI_REG_P(X) (REG_P (X) && REGNO (X) <= BX_REG)
 
index 0b207b5e8d446803e260f1e92811ab05c1765d2b..fe97f206f96246c6a6e0da76b77f54779b5d36a4 100644 (file)
@@ -247,8 +247,6 @@ enum reg_class
         ? (GR_REGS)                                            \
         : (CLASS))))
 
-#define SMALL_REGISTER_CLASSES 0
-
 #define CLASS_MAX_NREGS(CLASS, MODE)    \
   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
index 78e3115c291efdf9b8f7674747e82de02d9f08c9..85dc2d1dce29c0be8c6779a57a8510fca5b1f5b8 100644 (file)
@@ -421,7 +421,7 @@ enum reg_class
 
 #define SECONDARY_RELOAD_CLASS(CLASS,MODE,X) m32c_secondary_reload_class (CLASS, MODE, X)
 
-#define SMALL_REGISTER_CLASSES 1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define CLASS_LIKELY_SPILLED_P(C) m32c_class_likely_spilled_p (C)
 
index 278ba15c4facd636c547e20ebc48599147034ca4..b9626e1ecca6545e456e7207ff1ed9ee632dfaa9 100644 (file)
@@ -707,7 +707,7 @@ extern enum reg_class m68hc11_tmp_regs_class;
 
 #define PREFERRED_RELOAD_CLASS(X,CLASS)        preferred_reload_class(X,CLASS)
 
-#define SMALL_REGISTER_CLASSES 1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 /* A C expression that is nonzero if hard register number REGNO2 can be
    considered for use as a rename register for REGNO1 */
index 630a11fda1e56b3603c1c34255e24f8d0227246c..8167400633f47ae04f7b8829c1ad91b20f9a54a0 100644 (file)
@@ -406,10 +406,11 @@ enum reg_class
 extern const enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #define REGNO_REG_CLASS(REGNO) regno_reg_class[REGNO]
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers.  */
-#define SMALL_REGISTER_CLASSES 1
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
  
 /* The class value for index registers, and the one for base regs.  */
 #define INDEX_REG_CLASS  NO_REGS
index e4fbb32b9591223e8979e123e5195601f3484900..89a000728391b3f301d5ef503046a82ba7678e77 100644 (file)
@@ -291,6 +291,7 @@ extern rtx mips_function_value (const_tree, const_tree, enum machine_mode);
 
 extern bool mips_cannot_change_mode_class (enum machine_mode,
                                           enum machine_mode, enum reg_class);
+extern bool mips_small_register_classes_for_mode_p (enum machine_mode);
 extern bool mips_dangerous_for_la25_p (rtx);
 extern bool mips_modes_tieable_p (enum machine_mode, enum machine_mode);
 extern enum reg_class mips_preferred_reload_class (rtx, enum reg_class);
index eeff72d4b3378c4b055c551cb09a0d65f927c2f0..e246981222e7d7dc242007d6c969208901bb9506 100644 (file)
@@ -10718,6 +10718,15 @@ mips_cannot_change_mode_class (enum machine_mode from ATTRIBUTE_UNUSED,
   return reg_classes_intersect_p (FP_REGS, rclass);
 }
 
+/* Implement target hook small_register_classes_for_mode_p.  */
+
+static bool
+mips_small_register_classes_for_mode_p (enum machine_mode mode
+                                       ATTRIBUTE_UNUSED)
+{
+  return TARGET_MIPS16;
+}
+
 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction.  */
 
 static bool
index f5f0bd4e4df1e81df4c14f44165bf264bfa2c159..d5c98a6ffb89d026ca4e23f3b2c074ce2af5af90 100644 (file)
@@ -2006,12 +2006,12 @@ enum reg_class
 
 #define INDEX_REG_CLASS NO_REGS
 
-/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
+/* When this hook returns true for MODE, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
    registers.  */
-
-#define SMALL_REGISTER_CLASSES (TARGET_MIPS16)
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  mips_small_register_classes_for_mode_p
 
 /* We generally want to put call-clobbered registers ahead of
    call-saved ones.  (IRA expects this.)  */
index 3d9933e18aa43b1b62524a47cb80872334933b00..12e7861201430d87937490b068d79cd9c7a97936 100644 (file)
@@ -237,7 +237,7 @@ extern enum processor_type mn10300_processor;
 
 /* 4 data, and effectively 3 address registers is small as far as I'm
    concerned.  */
-#define SMALL_REGISTER_CLASSES 1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 \f
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
index fe8c9e8aed3b85cd40495062dd9dc36c8753edb6..a08f7239e10f7bd613236b59512602e0ef8cc11c 100644 (file)
@@ -290,7 +290,7 @@ enum reg_class { NO_REGS, MUL_REGS, GENERAL_REGS, LOAD_FPU_REGS, NO_LOAD_FPU_REG
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
 /* have to allow this till cmpsi/tstsi are fixed in a better way !! */
-#define SMALL_REGISTER_CLASSES 1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 /* Since GENERAL_REGS is the same class as ALL_REGS,
    don't give it a different class number; just make it an alias.  */
index a053340c48a4009d4df592a13202b3091c1ff763..8be66b53d9b18e7f8f7291a6fd23aa21e30699ff 100644 (file)
@@ -196,7 +196,6 @@ enum reg_class
     GR_REGS, LIM_REG_CLASSES                           \
   }
 
-#define SMALL_REGISTER_CLASSES                 0
 #define N_REG_CLASSES                  (int) LIM_REG_CLASSES
 #define CLASS_MAX_NREGS(CLASS, MODE)    ((GET_MODE_SIZE (MODE) \
                                          + UNITS_PER_WORD - 1) \
index fdef756b1645ce1a81f8520bd6ff735819577f20..d59cf6ab1182f61cb4e287c3035e8273a107be72 100644 (file)
@@ -145,6 +145,7 @@ extern int sh_attr_renesas_p (const_tree);
 extern int sh_cfun_attr_renesas_p (void);
 extern bool sh_cannot_change_mode_class
              (enum machine_mode, enum machine_mode, enum reg_class);
+extern bool sh_small_register_classes_for_mode_p (enum machine_mode);
 extern void sh_mark_label (rtx, int);
 extern int sh_register_move_cost
   (enum machine_mode mode, enum reg_class, enum reg_class);
index a3084b91a0b3980b5b7f8698b4ed9947bbaffe21..c3293fe05a572afb3887355ca9c65eedf07ef5f8 100644 (file)
@@ -865,7 +865,7 @@ sh_override_options (void)
       || (TARGET_SHMEDIA && !TARGET_PT_FIXED))
     flag_no_function_cse = 1;
 
-  if (SMALL_REGISTER_CLASSES)
+  if (targetm.small_register_classes_for_mode_p (VOIDmode))            \
     {
       /* Never run scheduling before reload, since that can
         break global alloc, and generates slower code anyway due
@@ -9311,7 +9311,7 @@ get_free_reg (HARD_REG_SET regs_live)
   if (! TEST_HARD_REG_BIT (regs_live, 1))
     return gen_rtx_REG (Pmode, 1);
 
-  /* Hard reg 1 is live; since this is a SMALL_REGISTER_CLASSES target,
+  /* Hard reg 1 is live; since this is a small register classes target,
      there shouldn't be anything but a jump before the function end.  */
   gcc_assert (!TEST_HARD_REG_BIT (regs_live, 7));
   return gen_rtx_REG (Pmode, 7);
@@ -11252,6 +11252,14 @@ sh_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
   return 0;
 }
 
+/* Return true if registers in machine mode MODE will likely be
+   allocated to registers in small register classes.  */
+
+static bool
+sh_small_register_classes_for_mode_p (enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return (! TARGET_SHMEDIA);
+}
 
 /* If ADDRESS refers to a CODE_LABEL, add NUSES to the number of times
    that label is used.  */
index f870ba69e98a390161bf46693b001753bcc4e1e7..4eb8f397ef97a0eee4c689f10b138aeca7f109e9 100644 (file)
@@ -1209,11 +1209,12 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
   FPUL_REGS, LIM_REG_CLASSES                                                \
 }
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers.  */
-
-#define SMALL_REGISTER_CLASSES (! TARGET_SHMEDIA)
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  sh_small_register_classes_for_mode_p
 
 /* The order in which register should be allocated.  */
 /* Sometimes FP0_REGS becomes the preferred class of a floating point pseudo,
index d7cab5a1ed20b93393a0f0598361620823b47eae..80c296d930ffe58d24d53c6ceddada1fa1d12aa1 100644 (file)
@@ -477,10 +477,10 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 #define BASE_REG_CLASS AR_REGS
 #define INDEX_REG_CLASS NO_REGS
 
-/* SMALL_REGISTER_CLASSES is required for Xtensa, because all of the
-   16 AR registers may be explicitly used in the RTL, as either
-   incoming or outgoing arguments.  */
-#define SMALL_REGISTER_CLASSES 1
+/* The small_register_classes_for_mode_p hook must always return true for
+   Xtrnase, because all of the 16 AR registers may be explicitly used in
+   the RTL, as either incoming or outgoing arguments.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
   xtensa_preferred_reload_class (X, CLASS, 0)
index 585cce8efd0b2cf3192bb3179ab49e593b3b36ba..98ef8d93d3cf3cf16d5d9fb2ad9936785014a347 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -686,7 +686,7 @@ approx_reg_cost_1 (rtx *xp, void *data)
        {
          if (regno < FIRST_PSEUDO_REGISTER)
            {
-             if (SMALL_REGISTER_CLASSES)
+             if (targetm.small_register_classes_for_mode_p (GET_MODE (x)))
                return 1;
              *cost_p += 2;
            }
@@ -2304,7 +2304,7 @@ hash_rtx_cb (const_rtx x, enum machine_mode mode,
              record = true;
            else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
              record = true;
-           else if (SMALL_REGISTER_CLASSES)
+           else if (targetm.small_register_classes_for_mode_p (GET_MODE (x)))
              record = false;
            else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
              record = false;
index a20d48c9f9cfa0d73659110c8035b1c190210422..3a36314d00fcfe4a5208a18e8e127d2449c0aefe 100644 (file)
@@ -2868,25 +2868,6 @@ Do not define this macro if you do not define
 is @code{BITS_PER_WORD} bits wide is correct for your machine.
 @end defmac
 
-@defmac SMALL_REGISTER_CLASSES
-On some machines, it is risky to let hard registers live across arbitrary
-insns.  Typically, these machines have instructions that require values
-to be in specific registers (like an accumulator), and reload will fail
-if the required hard register is used for another purpose across such an
-insn.
-
-Define @code{SMALL_REGISTER_CLASSES} to be an expression with a nonzero
-value on these machines.  When this macro has a nonzero value, the
-compiler will try to minimize the lifetime of hard registers.
-
-It is always safe to define this macro with a nonzero value, but if you
-unnecessarily define it, you will reduce the amount of optimizations
-that can be performed in some cases.  If you do not define this macro
-with a nonzero value when it is required, the compiler will run out of
-spill registers and print a fatal error message.  For most machines, you
-should not define this macro at all.
-@end defmac
-
 @defmac CLASS_LIKELY_SPILLED_P (@var{class})
 A C expression whose value is nonzero if pseudos that have been assigned
 to registers of class @var{class} would likely be spilled because
@@ -4360,6 +4341,38 @@ insns involving vector mode @var{mode}.  At the very least, it
 must have move patterns for this mode.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (enum machine_mode @var{mode})
+Define this to return nonzero for machine modes for which the port has
+small register classes.  If this target hook returns nonzero for a given
+@var{mode}, the compiler will try to minimize the lifetime of registers
+in @var{mode}.  The hook may be called with @code{VOIDmode} as argument.
+In this case, the hook is expected to return nonzero if it returns nonzero
+for any mode.
+
+On some machines, it is risky to let hard registers live across arbitrary
+insns.  Typically, these machines have instructions that require values
+to be in specific registers (like an accumulator), and reload will fail
+if the required hard register is used for another purpose across such an
+insn.
+
+Passes before reload do not know which hard registers will be used
+in an instruction, but the machine modes of the registers set or used in
+the instruction are already known.  And for some machines, register
+classes are small for, say, integer registers but not for floating point
+registers.  For example, the AMD x86-64 architecture requires specific
+registers for the legacy x86 integer instructions, but there are many
+SSE registers for floating point operations.  On such targets, a good
+strategy may be to return nonzero from this hook for @code{INTEGRAL_MODE_P}
+machine modes but zero for the SSE register classes.
+
+The default version of this hook retuns false for any mode.  It is always
+safe to redefine this hook to return with a nonzero value.  But if you
+unnecessarily define it, you will reduce the amount of optimizations
+that can be performed in some cases.  If you do not define this hook
+to return a nonzero value when it is required, the compiler will run out
+of spill registers and print a fatal error message.
+@end deftypefn
+
 @node Scalar Return
 @subsection How Scalar Function Values Are Returned
 @cindex return values in registers
index 8e31ee11a589cfe5e39262ffd34db6f2064aa2b6..033ec54f380f4db0229a5d7309a47458e4ac5d81 100644 (file)
@@ -3479,10 +3479,10 @@ insert_insn_end_basic_block (struct expr *expr, basic_block bb, int pre)
           && (!single_succ_p (bb)
               || single_succ_edge (bb)->flags & EDGE_ABNORMAL))
     {
-      /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
-        we search backward and place the instructions before the first
-        parameter is loaded.  Do this for everyone for consistency and a
-        presumption that we'll get better code elsewhere as well.
+      /* Keeping in mind targets with small register classes and parameters
+         in registers, we search backward and place the instructions before
+        the first parameter is loaded.  Do this for everyone for consistency
+        and a presumption that we'll get better code elsewhere as well.
 
         It should always be the case that we can put these instructions
         anywhere in the basic block with performing PRE optimizations.
index fd3c837fffe54dbcc363879e5e8261d5eae2f920..aac44485898f0a794144d58121e63e63ea814ec7 100644 (file)
@@ -70,6 +70,13 @@ hook_bool_mode_false (enum machine_mode mode ATTRIBUTE_UNUSED)
   return false;
 }
 
+/* Generic hook that takes (enum machine_mode) and returns true.  */
+bool
+hook_bool_mode_true (enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
 /* Generic hook that takes (enum machine_mode, rtx) and returns false.  */
 bool
 hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
index 38296da2af945357dc712295e5dec7959d22ed28..5fd8296c75a507a905d717ec64820f201619e089 100644 (file)
@@ -30,6 +30,7 @@ extern bool hook_bool_void_true (void);
 extern bool hook_bool_bool_false (bool);
 extern bool hook_bool_const_int_const_int_true (const int, const int);
 extern bool hook_bool_mode_false (enum machine_mode);
+extern bool hook_bool_mode_true (enum machine_mode);
 extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
 extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
 extern bool hook_bool_tree_false (tree);
index 1ef32414aaafe6a5887a8bdc0a259bd0fddf8c33..18c771bf51e3b0644ca9e65c1e499ba35d854fb0 100644 (file)
@@ -2405,8 +2405,8 @@ noce_process_if_block (struct noce_if_info *if_info)
      the lifetime of hard registers on small register class machines.  */
   orig_x = x;
   if (!REG_P (x)
-      || (SMALL_REGISTER_CLASSES
-         && REGNO (x) < FIRST_PSEUDO_REGISTER))
+      || (HARD_REGISTER_P (x)
+         && targetm.small_register_classes_for_mode_p (GET_MODE (x))))
     {
       if (GET_MODE (x) == BLKmode)
        return FALSE;
@@ -2605,7 +2605,8 @@ check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
       dest = SET_DEST (set);
       src = SET_SRC (set);
       if (!REG_P (dest)
-         || (SMALL_REGISTER_CLASSES && HARD_REGISTER_P (dest)))
+         || (HARD_REGISTER_P (dest)
+             && targetm.small_register_classes_for_mode_p (GET_MODE (dest))))
        return FALSE;
 
       if (!CONSTANT_P (src) && !register_operand (src, VOIDmode))
@@ -4061,7 +4062,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
 
       /* For small register class machines, don't lengthen lifetimes of
         hard registers before reload.  */
-      if (SMALL_REGISTER_CLASSES && ! reload_completed)
+      if (! reload_completed
+         && targetm.small_register_classes_for_mode_p (VOIDmode))
        {
           EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
            {
index 25fcc52b213b3ce35ce618b7d6ec44ded9afbad8..c9e947eae6496e14a1ba64bcf4204ea31c030a9a 100644 (file)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm_p.h"
 #include "insn-config.h"
 #include "recog.h"
+#include "target.h"
 #include "output.h"
 #include "regs.h"
 #include "hard-reg-set.h"
@@ -239,7 +240,7 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
 
   /* We don't want to mess with hard regs if register classes are small.  */
   if (sregno == dregno
-      || (SMALL_REGISTER_CLASSES
+      || (targetm.small_register_classes_for_mode_p (GET_MODE (src))
          && (sregno < FIRST_PSEUDO_REGISTER
              || dregno < FIRST_PSEUDO_REGISTER))
       /* We don't see all updates to SP if they are in an auto-inc memory
index 63235504e9c21c33a085b4e6bcc951359e976d6e..01325b09e91bfae97f3edc9c88f78d1eafe74892 100644 (file)
@@ -37,10 +37,6 @@ along with GCC; see the file COPYING3.  If not see
 #define REGMODE_NATURAL_SIZE(MODE)     UNITS_PER_WORD
 #endif
 
-#ifndef SMALL_REGISTER_CLASSES
-#define SMALL_REGISTER_CLASSES 0
-#endif
-
 /* Maximum register number used in this function, plus one.  */
 
 extern int max_regno;
index 2406b6bc5503fb9512d74ca7729ae2cdd5c46d52..ac2fa46cb40bad873564d0e54bad6c3074eb3fc2 100644 (file)
@@ -438,7 +438,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
            || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
        && ((in_p && rld[s_reload].secondary_in_icode == t_icode)
            || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
-       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass)
+           || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
                             opnum, rld[s_reload].opnum))
       {
@@ -731,9 +732,9 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
      and the other is at worst neutral.
      (A zero compared against anything is neutral.)
 
-     If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
-     for the same thing since that can cause us to need more reload registers
-     than we otherwise would.  */
+     For targets with small register classes, don't use existing reloads
+     unless they are for the same thing since that can cause us to need
+     more reload registers than we otherwise would.  */
 
   for (i = 0; i < n_reloads; i++)
     if ((reg_class_subset_p (rclass, rld[i].rclass)
@@ -747,7 +748,8 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
            || (out != 0 && MATCHES (rld[i].out, out)
                && (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass)
+           || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
       return i;
 
@@ -772,7 +774,8 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
                && GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
                && MATCHES (XEXP (in, 0), rld[i].in)))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass)
+           || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (type, rld[i].when_needed,
                             opnum, rld[i].opnum))
       {
@@ -1770,7 +1773,7 @@ combine_reloads (void)
            || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
                            secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
 #endif
-       && (SMALL_REGISTER_CLASSES
+       && (targetm.small_register_classes_for_mode_p (VOIDmode)
            ? (rld[i].rclass == rld[output_reload].rclass)
            : (reg_class_subset_p (rld[i].rclass,
                                   rld[output_reload].rclass)
@@ -1794,7 +1797,7 @@ combine_reloads (void)
        && ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
                                         rld[i].when_needed != RELOAD_FOR_INPUT)
        && (reg_class_size[(int) rld[i].rclass]
-           || SMALL_REGISTER_CLASSES)
+           || targetm.small_register_classes_for_mode_p (VOIDmode))
        /* We will allow making things slightly worse by combining an
           input and an output, but no worse than that.  */
        && (rld[i].when_needed == RELOAD_FOR_INPUT
index bd590cbc9c9b37ada64f3eccfadd5cc098a221cc..ce0b602a7cf4a6c87498683c1ab6d4dddf2301cc 100644 (file)
@@ -4281,7 +4281,7 @@ reload_as_needed (int live_known)
              /* Merge any reloads that we didn't combine for fear of
                 increasing the number of spill registers needed but now
                 discover can be safely merged.  */
-             if (SMALL_REGISTER_CLASSES)
+             if (targetm.small_register_classes_for_mode_p (VOIDmode))
                merge_assigned_reloads (insn);
 
              /* Generate the insns to reload operands into or out of
@@ -6667,10 +6667,11 @@ deallocate_reload_reg (int r)
   reload_spill_index[r] = -1;
 }
 \f
-/* If SMALL_REGISTER_CLASSES is nonzero, we may not have merged two
-   reloads of the same item for fear that we might not have enough reload
-   registers. However, normally they will get the same reload register
-   and hence actually need not be loaded twice.
+/* If the small_register_classes_for_mode_p target hook returns true for
+   some machine modes, we may not have merged two reloads of the same item
+   for fear that we might not have enough reload registers.  However,
+   normally they will get the same reload register and hence actually need
+   not be loaded twice.
 
    Here we check for the most common case of this phenomenon: when we have
    a number of reloads for the same object, each of which were allocated
index 974ffd779b024e425637d6b80e2e8d05f48fe29b..34d20e5f654614e017d9d0697d4583c94e3b9de1 100644 (file)
@@ -3056,8 +3056,8 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn)
      This insn must be a simple move of a hard reg to a pseudo or
      vice-versa.
 
-     We must avoid moving these insns for correctness on
-     SMALL_REGISTER_CLASS machines, and for special registers like
+     We must avoid moving these insns for correctness on targets
+     with small register classes, and for special registers like
      PIC_OFFSET_TABLE_REGNUM.  For simplicity, extend this to all
      hard regs for all targets.  */
 
index feca6c5270c22ca3c47599227f1850cdeafa38c8..1c734369c23dd6ce26952f433959de81a0ab77ea 100644 (file)
 #define TARGET_VECTOR_MODE_SUPPORTED_P hook_bool_mode_false
 #endif
 
+#ifndef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_false
+#endif
+
 /* In hooks.c.  */
 #define TARGET_CANNOT_MODIFY_JUMPS_P hook_bool_void_false
 #define TARGET_BRANCH_TARGET_REGISTER_CLASS \
   TARGET_ADDR_SPACE_HOOKS,                     \
   TARGET_SCALAR_MODE_SUPPORTED_P,              \
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
+  TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P,    \
   TARGET_RTX_COSTS,                            \
   TARGET_ADDRESS_COST,                         \
   TARGET_ALLOCATE_INITIAL_VALUE,               \
   TARGET_MACHINE_DEPENDENT_REORG,              \
   TARGET_BUILD_BUILTIN_VA_LIST,                        \
   TARGET_FN_ABI_VA_LIST,                       \
-  TARGET_CANONICAL_VA_LIST_TYPE,                       \
+  TARGET_CANONICAL_VA_LIST_TYPE,               \
   TARGET_EXPAND_BUILTIN_VA_START,              \
   TARGET_GIMPLIFY_VA_ARG_EXPR,                 \
   TARGET_GET_PCH_VALIDITY,                     \
index 62a1bcc3d7e3a04d37e4699451fc68894c5c7b56..6ff7d1d639e0368bea403b721025621cc1524bd1 100644 (file)
@@ -762,6 +762,12 @@ struct gcc_target
      for further details.  */
   bool (* vector_mode_supported_p) (enum machine_mode mode);
 
+  /* True for MODE if the target expects that registers in this mode will
+     be allocated to registers in a small register class.  The compiler is
+     allowed to use registers explicitly used in the rtl as spill registers
+     but it should prevent extending the lifetime of these registers.  */
+  bool (* small_register_classes_for_mode_p) (enum machine_mode mode);
+
   /* Compute a (partial) cost for rtx X.  Return true if the complete
      cost has been computed, and false if subexpressions should be
      scanned.  In either case, *TOTAL contains the cost result.  */