Patchwork Hookize REGISTER_MOVE_COST

login
register
mail settings
Submitter Anatoly Sokolov
Date June 17, 2010, 9:07 p.m.
Message ID <1978238683.20100618010728@post.ru>
Download mbox | patch
Permalink /patch/56090/
State New
Headers show

Comments

Anatoly Sokolov - June 17, 2010, 9:07 p.m.
Hello.

  This patch turns REGISTER_MOVE_COST macro into a hook.

  The patch has been bootstrapped on and regression tested on
x86_64-unknown-linux-gnu and ia64-unknown-linux-gnu for c, c++ and ada.

  This patch is pre-approved and should be committed within a week if no
objections.

        * target.h (struct gcc_target): Add register_move_cost field.
        * target-def.h (TARGET_REGISTER_MOVE_COST): New.
        (TARGET_INITIALIZER): Use TARGET_REGISTER_MOVE_COST.
        * targhooks.c (default_register_move_cost): New function.
        * targhooks.h (default_register_move_cost): Declare function.
        * defaults.h (REGISTER_MOVE_COST): Delete.
        * ira-int.h (ira_register_move_cost): Update comment.
        * ira.c: (ira_register_move_cost): Update comment.
        * reload.h (register_move_cost): Declare.
        * reginfo.c (register_move_cost): New function.
        (move_cost): Update comment.
        (init_move_cost, memory_move_secondary_cost): Replace
        REGISTER_MOVE_COST with register_move_cost.
        * postreload.c (reload_cse_simplify_set): (Ditto.).
        * reload.c (find_valid_class, find_reloads): (Ditto.).
        * reload1.c (choose_reload_regs): (Ditto.).
        * doc/tm.texi (TARGET_REGISTER_MOVE_COST): New.
        (REGISTER_MOVE_COST, TARGET_MEMORY_MOVE_COST): Update documentation.
        * doc/md.texi (can_create_pseudo_p): Update documentation.

        * config/i386/i386.h (MEMORY_MOVE_COST): Remove macro.
        * config/i386/i386-protos.h (int ix86_memory_move_cost): Remove.
        * config/i386/i386.h (ix86_memory_move_cost): Make static.
        (TARGET_MEMORY_MOVE_COST): Define.

        * config/ia64/ia64.h (MEMORY_MOVE_COST): Remove macro.
        * config/ia64/ia64-protos.h (int ia64_memory_move_cost): Remove.
        * config/ia64/ia64.h (ia64_memory_move_cost): Make static.
        (TARGET_MEMORY_MOVE_COST): Define





Anatoly.

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 160945)
+++ gcc/doc/tm.texi     (working copy)
@@ -6148,8 +6148,32 @@ 
 constraints of the insn are met.  Setting a cost of other than 2 will
 allow reload to verify that the constraints are met.  You should do this
 if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
+
+These macros are obsolete, new ports should use the target hook
+@code{TARGET_REGISTER_MOVE_COST} instead.
 @end defmac
 
+@deftypefn {Target Hook} int TARGET_REGISTER_MOVE_COST (enum machine_mode @var{mode}, enum reg_class @var{from}, enum reg_class @var{to})
+This target hook should return the cost of moving data of mode @var{mode}
+from a register in class @var{from} to one in class @var{to}.  The classes
+are expressed using the enumeration values such as @code{GENERAL_REGS}.
+A value of 2 is the default; other values are interpreted relative to
+that.
+
+It is not required that the cost always equal 2 when @var{from} is the
+same as @var{to}; on some machines it is expensive to move between
+registers if they are not general registers.
+
+If reload sees an insn consisting of a single @code{set} between two
+hard registers, and if @code{TARGET_REGISTER_MOVE_COST} applied to their
+classes returns a value of 2, reload does not check to ensure that the
+constraints of the insn are met.  Setting a cost of other than 2 will
+allow reload to verify that the constraints are met.  You should do this
+if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
+
+The default version of this function returns 2.
+@end deftypefn
+
 @defmac MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
 A C expression for the cost of moving data of mode @var{mode} between a
 register of class @var{class} and memory; @var{in} is zero if the value
@@ -6181,9 +6205,9 @@ 
 This target hook should return the cost of moving data of mode @var{mode}
 between a register of class @var{class} and memory; @var{in} is @code{false}
 if the value is to be written to memory, @code{true} if it is to be read in.
-This cost is relative to those in @code{REGISTER_MOVE_COST}.  If moving
-between registers and memory is more expensive than between two registers,
-you should add this target hook to express the relative cost.
+This cost is relative to those in @code{TARGET_REGISTER_MOVE_COST}.
+If moving between registers and memory is more expensive than between two
+registers, you should add this target hook to express the relative cost.
 
 If you do not add this target hook, GCC uses a default cost of 4 plus
 the cost of copying via a secondary reload register, if one is
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi     (revision 160945)
+++ gcc/doc/md.texi     (working copy)
@@ -3750,7 +3750,8 @@ 
 The constraints on a @samp{mov@var{m}} must permit moving any hard
 register to any other hard register provided that
 @code{HARD_REGNO_MODE_OK} permits mode @var{m} in both registers and
-@code{REGISTER_MOVE_COST} applied to their classes returns a value of 2.
+@code{TARGET_REGISTER_MOVE_COST} applied to their classes returns a value
+of 2.
 
 It is obligatory to support floating point @samp{mov@var{m}}
 instructions into and out of any registers that can hold fixed point
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     (revision 160945)
+++ gcc/targhooks.c     (working copy)
@@ -1127,4 +1127,19 @@ 
 #endif
 }
 
+/* Compute cost of moving data from a register of class FROM to one of
+   TO, using MODE.  */
+
+int
+default_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+                            enum reg_class from ATTRIBUTE_UNUSED,
+                            enum reg_class to ATTRIBUTE_UNUSED)
+{
+#ifndef REGISTER_MOVE_COST
+  return 2;
+#else
+  return REGISTER_MOVE_COST (mode, from, to);
+#endif
+}
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     (revision 160945)
+++ gcc/targhooks.h     (working copy)
@@ -140,3 +140,6 @@ 
 extern unsigned int default_case_values_threshold (void);
 extern bool default_have_conditional_execution (void);
 extern int default_memory_move_cost (enum machine_mode, enum reg_class, bool);
+extern int default_register_move_cost (enum machine_mode, enum reg_class,
+                                      enum reg_class);
+
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h      (revision 160945)
+++ gcc/defaults.h      (working copy)
@@ -981,10 +981,6 @@ 
 
 #endif /* old constraint mechanism in use */
 
-#ifndef REGISTER_MOVE_COST
-#define REGISTER_MOVE_COST(m, x, y) 2
-#endif
-
 /* Determine whether the entire c99 runtime
    is present in the runtime library.  */
 #ifndef TARGET_C99_FUNCTIONS
Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c    (revision 160945)
+++ gcc/postreload.c    (working copy)
@@ -264,7 +264,7 @@ 
   if (MEM_P (src))
     old_cost = memory_move_cost (GET_MODE (src), dclass, true);
   else if (REG_P (src))
-    old_cost = REGISTER_MOVE_COST (GET_MODE (src),
+    old_cost = register_move_cost (GET_MODE (src),
                                   REGNO_REG_CLASS (REGNO (src)), dclass);
   else
     old_cost = rtx_cost (src, SET, speed);
@@ -314,7 +314,7 @@ 
            }
          else
 #endif
-           this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
+           this_cost = register_move_cost (GET_MODE (this_rtx),
                                            REGNO_REG_CLASS (REGNO (this_rtx)),
                                            dclass);
        }
Index: gcc/reload.c
===================================================================
--- gcc/reload.c        (revision 160945)
+++ gcc/reload.c        (working copy)
@@ -688,7 +688,7 @@ 
 
       if (bad || !good)
        continue;
-      cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class);
+      cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);
 
       if ((reg_class_size[rclass] > best_size
           && (best_cost < 0 || best_cost >= cost))
@@ -696,7 +696,7 @@ 
        {
          best_class = (enum reg_class) rclass;
          best_size = reg_class_size[rclass];
-         best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass,
+         best_cost = register_move_cost (outer, (enum reg_class) rclass,
                                          dest_class);
        }
     }
@@ -2651,7 +2651,7 @@ 
       && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
       && REG_P (SET_SRC (body))
       && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
-      && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
+      && register_move_cost (GET_MODE (SET_SRC (body)),
                             REGNO_REG_CLASS (REGNO (SET_SRC (body))),
                             REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
     return 0;
Index: gcc/reload.h
===================================================================
--- gcc/reload.h        (revision 160945)
+++ gcc/reload.h        (working copy)
@@ -30,6 +30,8 @@ 
   SECONDARY_RELOAD_CLASS (CLASS, MODE, X)
 #endif
 
+extern int register_move_cost (enum machine_mode, enum reg_class,
+                              enum reg_class);
 extern int memory_move_cost (enum machine_mode, enum reg_class, bool);
 extern int memory_move_secondary_cost (enum machine_mode, enum reg_class,
                                       bool);
Index: gcc/target.h
===================================================================
--- gcc/target.h        (revision 160945)
+++ gcc/target.h        (working copy)
@@ -812,6 +812,11 @@ 
      for further details.  */
   bool (* vector_mode_supported_p) (enum machine_mode mode);
 
+  /* Compute cost of moving data from a register of class FROM to one of
+     TO, using MODE.  */
+  int (* register_move_cost) (enum machine_mode, enum reg_class,
+                             enum reg_class);
+
   /* Compute cost of moving registers to/from memory.  */
   int (* memory_move_cost) (enum machine_mode, enum reg_class, bool);
 
Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h       (revision 160945)
+++ gcc/ira-int.h       (working copy)
@@ -719,7 +719,7 @@ 
 extern HARD_REG_SET ira_reg_mode_hard_regset
                     [FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
 
-/* Array analogous to macro REGISTER_MOVE_COST.  Don't use
+/* Array based on TARGET_REGISTER_MOVE_COST.  Don't use
    ira_register_move_cost directly.  Use function of
    ira_get_may_move_cost instead.  */
 extern move_table *ira_register_move_cost[MAX_MACHINE_MODE];
Index: gcc/ira.c
===================================================================
--- gcc/ira.c   (revision 160945)
+++ gcc/ira.c   (working copy)
@@ -361,7 +361,7 @@ 
 /* Array analogous to target hook TARGET_MEMORY_MOVE_COST.  */
 short int ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
 
-/* Array analogous to macro REGISTER_MOVE_COST.  */
+/* Array based on TARGET_REGISTER_MOVE_COST.  */
 move_table *ira_register_move_cost[MAX_MACHINE_MODE];
 
 /* Similar to may_move_in_cost but it is calculated in IRA instead of
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h    (revision 160945)
+++ gcc/target-def.h    (working copy)
@@ -474,6 +474,10 @@ 
 #define TARGET_ADDRESS_COST default_address_cost
 #define TARGET_CONST_ANCHOR 0
 
+#ifndef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST default_register_move_cost
+#endif
+
 #ifndef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST default_memory_move_cost
 #endif
@@ -1027,6 +1031,7 @@ 
   TARGET_ADDR_SPACE_HOOKS,                     \
   TARGET_SCALAR_MODE_SUPPORTED_P,              \
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
+  TARGET_REGISTER_MOVE_COST,                   \
   TARGET_MEMORY_MOVE_COST,                     \
   TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P,    \
   TARGET_RTX_COSTS,                            \
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c       (revision 160945)
+++ gcc/reginfo.c       (working copy)
@@ -183,7 +183,7 @@ 
 char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE];
 
 /* Maximum cost of moving from a register in one class to a register in
-   another class.  Based on REGISTER_MOVE_COST.  */
+   another class.  Based on TARGET_REGISTER_MOVE_COST.  */
 move_table *move_cost[MAX_MACHINE_MODE];
 
 /* Similar, but here we don't have to move if the first index is a subset
@@ -274,7 +274,7 @@ 
            cost = 65535;
          else
            {
-             cost = REGISTER_MOVE_COST (m, (enum reg_class) i,
+             cost = register_move_cost (m, (enum reg_class) i,
                                         (enum reg_class) j);
              gcc_assert (cost < 65535);
            }
@@ -681,6 +681,17 @@ 
     top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx);
 }
 
+
+/* Compute cost of moving data from a register of class FROM to one of
+   TO, using MODE.  */
+
+int
+register_move_cost (enum machine_mode mode, enum reg_class from,
+                    enum reg_class to)
+{
+  return targetm.register_move_cost (mode, from, to);
+}
+
 /* Compute cost of moving registers to/from memory.  */
 int
 memory_move_cost (enum machine_mode mode, enum reg_class rclass, bool in)
@@ -706,9 +717,9 @@ 
     return 0;
 
   if (in)
-    partial_cost = REGISTER_MOVE_COST (mode, altclass, rclass);
+    partial_cost = register_move_cost (mode, altclass, rclass);
   else
-    partial_cost = REGISTER_MOVE_COST (mode, rclass, altclass);
+    partial_cost = register_move_cost (mode, rclass, altclass);
 
   if (rclass == altclass)
     /* This isn't simply a copy-to-temporary situation.  Can't guess
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h      (revision 160945)
+++ gcc/config/i386/i386.h      (working copy)
@@ -1891,18 +1891,7 @@ 
    so give the MEM rtx a byte's mode.  */
 #define FUNCTION_MODE QImode
 
-/* A C expression for the cost of moving data from a register in class FROM to
-   one in class TO.  The classes are expressed using the enumeration values
-   such as `GENERAL_REGS'.  A value of 2 is the default; other values are
-   interpreted relative to that.
 
-   It is not required that the cost always equal 2 when FROM is the same as TO;
-   on some machines it is expensive to move between registers if they are not
-   general registers.  */
-
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
-   ix86_register_move_cost ((MODE), (CLASS1), (CLASS2))
-
 /* A C expression for the cost of a branch instruction.  A value of 1
    is the default; other values are interpreted relative to that.  */
 
Index: gcc/config/i386/i386-protos.h
===================================================================
--- gcc/config/i386/i386-protos.h       (revision 160945)
+++ gcc/config/i386/i386-protos.h       (working copy)
@@ -149,8 +149,6 @@ 
                                  rtx, rtx, rtx, rtx);
 extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
 extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode);
-extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
-                                   enum reg_class);
 extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
                                         enum machine_mode, int);
 extern bool ix86_cannot_change_mode_class (enum machine_mode,
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 160945)
+++ gcc/config/i386/i386.c      (working copy)
@@ -25599,7 +25599,7 @@ 
    on some machines it is expensive to move between registers if they are not
    general registers.  */
 
-int
+static int
 ix86_register_move_cost (enum machine_mode mode, enum reg_class class1,
                         enum reg_class class2)
 {
@@ -30771,6 +30771,8 @@ 
 #undef TARGET_HANDLE_OPTION
 #define TARGET_HANDLE_OPTION ix86_handle_option
 
+#undef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
 #undef TARGET_RTX_COSTS
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c      (revision 160945)
+++ gcc/config/ia64/ia64.c      (working copy)
@@ -210,6 +210,8 @@ 
 static rtx ia64_function_value (const_tree, const_tree, bool);
 static rtx ia64_libcall_value (enum machine_mode, const_rtx);
 static bool ia64_function_value_regno_p (const unsigned int);
+static int ia64_register_move_cost (enum machine_mode, enum reg_class,
+                                    enum reg_class);
 static bool ia64_rtx_costs (rtx, int, int, int *, bool);
 static int ia64_unspec_may_trap_p (const_rtx, unsigned);
 static void fix_range (const char *);
@@ -454,6 +456,8 @@ 
 #undef TARGET_ASM_GLOBALIZE_DECL_NAME
 #define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name
 
+#undef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST ia64_register_move_cost
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS ia64_rtx_costs
 #undef TARGET_ADDRESS_COST
@@ -5179,7 +5183,7 @@ 
 /* Calculate the cost of moving data from a register in class FROM to
    one in class TO, using MODE.  */
 
-int
+static int
 ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
                         enum reg_class to)
 {
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h      (revision 160945)
+++ gcc/config/ia64/ia64.h      (working copy)
@@ -1310,11 +1310,6 @@ 
 
 /* Describing Relative Costs of Operations */
 
-/* A C expression for the cost of moving data from a register in class FROM to
-   one in class TO, using MODE.  */
-
-#define REGISTER_MOVE_COST  ia64_register_move_cost
-
 /* A C expression for the cost of moving data of mode M between a
    register and memory.  */
 #define MEMORY_MOVE_COST(MODE,CLASS,IN) \
Index: gcc/config/ia64/ia64-protos.h
===================================================================
--- gcc/config/ia64/ia64-protos.h       (revision 160945)
+++ gcc/config/ia64/ia64-protos.h       (working copy)
@@ -81,8 +81,6 @@ 
 extern void ia64_vms_elf_asm_named_section (const char *, unsigned int, tree);
 #endif /* TREE_CODE */
 
-extern int ia64_register_move_cost (enum machine_mode, enum reg_class,
-                                   enum reg_class);
 extern int ia64_epilogue_uses (int);
 extern int ia64_eh_uses (int);
 extern void emit_safe_across_calls (void);
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c       (revision 160945)
+++ gcc/reload1.c       (working copy)
@@ -6500,7 +6500,7 @@ 
                             register, we might use it for reload_override_in,
                             if copying it to the desired class is cheap
                             enough.  */
-                         || ((REGISTER_MOVE_COST (mode, last_class, rclass)
+                         || ((register_move_cost (mode, last_class, rclass)
                               < memory_move_cost (mode, rclass, true))
                              && (secondary_reload_class (1, rclass, mode,
                                                          last_reg)