OSDN Git Service

* doc/tm.texi (defmac SMALL_REGISTER_CLASSES): Remove.
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 May 2010 17:47:47 +0000 (17:47 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 May 2010 17:47:47 +0000 (17:47 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158997 138bc75d-0d04-0410-961f-82ee72b054a4

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 485dfbe..727f897 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 496ec60..9c51f1a 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 13e0e5c..7fb1873 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 5a42a25..2933201 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 884a1bd..7f3cdfa 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 ca46db1..b672535 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 67e0c8f..398b412 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 365680e..a1bd556 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 f77dfa3..1ce1585 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 ebe3238..18e3eb3 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 0b207b5..fe97f20 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 78e3115..85dc2d1 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 278ba15..b9626e1 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 630a11f..8167400 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 e4fbb32..89a0007 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 eeff72d..e246981 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 f5f0bd4..d5c98a6 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 3d9933e..12e7861 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 fe8c9e8..a08f723 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 a053340..8be66b5 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 fdef756..d59cf6a 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 a3084b9..c3293fe 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 f870ba6..4eb8f39 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 d7cab5a..80c296d 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 585cce8..98ef8d9 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 a20d48c..3a36314 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 8e31ee1..033ec54 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 fd3c837..aac4448 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 38296da..5fd8296 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 1ef3241..18c771b 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 25fcc52..c9e947e 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 6323550..01325b0 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 2406b6b..ac2fa46 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 bd590cb..ce0b602 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 974ffd7..34d20e5 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 feca6c5..1c73436 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 62a1bcc..6ff7d1d 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.  */