[PATCH] Hookize MEMORY_MOVE_COST

Anatoly Sokolov aesok@post.ru
Sun May 30 12:03:00 GMT 2010


Hello.

  This patch turns MEMORY_MOVE_COST macro into a hook.

  The patch has been bootstrapped on and regression tested on
x86_64-unknown-linux-gnu.

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

        * target.h (struct gcc_target): Add memory_move_cost field.
        * target-def.h (TARGET_MEMORY_MOVE_COST): New.
        (TARGET_INITIALIZER): Use TARGET_MEMORY_MOVE_COST.
        * targhooks.c (default_memory_move_cost): New function.
        * targhooks.h (default_memory_move_cost): Declare function.
        * reload.h (memory_move_cost): Declare.
        (memory_move_secondary_cost): Change type of 'in' argument to bool.
        * reginfo.c (memory_move_cost): New function.
        (memory_move_secondary_cost): Change type of 'in' argument to bool.
        * ira.h (ira_memory_move_cost): Update comment.
        * ira.c: (ira_memory_move_cost): Update comment.
        (setup_class_subset_and_memory_move_costs): Replace MEMORY_MOVE_COST
        with memory_move_cost.
        * postreload.c (reload_cse_simplify_set): (Ditto.).
        * reload1.c (choose_reload_regs): (Ditto.).
        * doc/tm.texi (TARGET_MEMORY_MOVE_COST): New.
        (MEMORY_MOVE_COST):  Revise 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. Change
        type of 'in' argument to bool.
        (TARGET_MEMORY_MOVE_COST): Define.


Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 160046)
+++ gcc/doc/tm.texi     (working copy)
@@ -6178,8 +6178,35 @@
 4 is not correct for your machine, define this macro to add some other
 value to the result of that function.  The arguments to that function
 are the same as to this macro.
+
+These macros are obsolete, new ports should use the target hook
+@code{TARGET_MEMORY_MOVE_COST} instead.
 @end defmac
 
+@deftypefn {Target Hook} int TARGET_MEMORY_MOVE_COST (enum machine_mode @var{mode}, enum reg_class @var{regclass}, bool @var{in})
+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.
+
+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
+needed.  If your machine requires a secondary reload register to copy
+between memory and a register of @var{class} but the reload mechanism is
+more complex than copying via an intermediate, use this target hook to
+reflect the actual cost of the move.
+
+GCC defines the function @code{memory_move_secondary_cost} if
+secondary reloads are needed.  It computes the costs due to copying via
+a secondary register.  If your machine copies from memory using a
+secondary register in the conventional way but the default base value of
+4 is not correct for your machine, use this target hook to add some other
+value to the result of that function.  The arguments to that function
+are the same as to this target hook.
+@end deftypefn
+
 @defmac BRANCH_COST (@var{speed_p}, @var{predictable_p})
 A C expression for the cost of a branch instruction.  A value of 1 is the
 default; other values are interpreted relative to that. Parameter @var{speed_p}
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     (revision 160046)
+++ gcc/targhooks.c     (working copy)
@@ -1048,4 +1048,18 @@
 #endif
 }
 
+/* Compute cost of moving registers to/from memory.  */
+
+int
+default_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+                         enum reg_class rclass ATTRIBUTE_UNUSED,
+                         bool in ATTRIBUTE_UNUSED)
+{
+#ifndef MEMORY_MOVE_COST
+    return (4 + memory_move_secondary_cost (mode, rclass, in));
+#else
+    return MEMORY_MOVE_COST (mode, rclass, in);
+#endif
+}
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     (revision 160046)
+++ gcc/targhooks.h     (working copy)
@@ -134,3 +134,4 @@
 extern rtx default_addr_space_convert (rtx, tree, tree);
 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);
Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c    (revision 160046)
+++ gcc/postreload.c    (working copy)
@@ -262,7 +262,7 @@
 
   /* If memory loads are cheaper than register copies, don't change them.  */
   if (MEM_P (src))
-    old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
+    old_cost = memory_move_cost (GET_MODE (src), dclass, true);
   else if (REG_P (src))
     old_cost = REGISTER_MOVE_COST (GET_MODE (src),
                                   REGNO_REG_CLASS (REGNO (src)), dclass);
Index: gcc/reload.h
===================================================================
--- gcc/reload.h        (revision 160046)
+++ gcc/reload.h        (working copy)
@@ -30,12 +30,9 @@
   SECONDARY_RELOAD_CLASS (CLASS, MODE, X)
 #endif
 
-/* If MEMORY_MOVE_COST isn't defined, give it a default here.  */
-#ifndef MEMORY_MOVE_COST
-#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
-  (4 + memory_move_secondary_cost ((MODE), (CLASS), (IN)))
-#endif
-extern int memory_move_secondary_cost (enum machine_mode, enum reg_class, int);
+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);
 
 /* Maximum number of reloads we can need.  */
 #define MAX_RELOADS (2 * MAX_RECOG_OPERANDS * (MAX_REGS_PER_ADDRESS + 1))
Index: gcc/target.h
===================================================================
--- gcc/target.h        (revision 160046)
+++ gcc/target.h        (working copy)
@@ -781,6 +781,9 @@
      for further details.  */
   bool (* vector_mode_supported_p) (enum machine_mode mode);
 
+  /* Compute cost of moving registers to/from memory.  */
+  int (* memory_move_cost) (enum machine_mode, enum reg_class, bool);
+
   /* 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
Index: gcc/ipa.c
===================================================================
--- gcc/ipa.c   (revision 160046)
+++ gcc/ipa.c   (working copy)
@@ -355,7 +355,7 @@
        }
     }
 
-  /* Remove unreachable nodes. 
+  /* Remove unreachable nodes.
 
      Completely unreachable functions can be fully removed from the callgraph.
      Extern inline functions that we decided to not inline need to become unanalyzed nodes of
Index: gcc/ira.c
===================================================================
--- gcc/ira.c   (revision 160046)
+++ gcc/ira.c   (working copy)
@@ -358,9 +358,10 @@
    of given mode starting with given hard register.  */
 HARD_REG_SET ira_reg_mode_hard_regset[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
 
-/* The following two variables are array analogs of the macros
-   MEMORY_MOVE_COST and REGISTER_MOVE_COST.  */
+/* 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.  */
 move_table *ira_register_move_cost[MAX_MACHINE_MODE];
 
 /* Similar to may_move_in_cost but it is calculated in IRA instead of
@@ -527,11 +528,11 @@
        for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
          {
            ira_memory_move_cost[mode][cl][0] =
-             MEMORY_MOVE_COST ((enum machine_mode) mode,
-                               (enum reg_class) cl, 0);
+             memory_move_cost ((enum machine_mode) mode,
+                               (enum reg_class) cl, false);
            ira_memory_move_cost[mode][cl][1] =
-             MEMORY_MOVE_COST ((enum machine_mode) mode,
-                               (enum reg_class) cl, 1);
+             memory_move_cost ((enum machine_mode) mode,
+                               (enum reg_class) cl, true);
            /* Costs for NO_REGS are used in cost calculation on the
               1st pass when the preferred register classes are not
               known yet.  In this case we take the best scenario.  */
Index: gcc/ira.h
===================================================================
--- gcc/ira.h   (revision 160046)
+++ gcc/ira.h   (working copy)
@@ -58,7 +58,7 @@
    mode or when the conflict table is too big.  */
 extern bool ira_conflicts_p;
 
-/* Array analogous to macro MEMORY_MOVE_COST.  */
+/* Array analogous to target hook TARGET_MEMORY_MOVE_COST.  */
 extern short ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
 
 /* Array of number of hard registers of given class which are
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h    (revision 160046)
+++ gcc/target-def.h    (working copy)
@@ -453,6 +453,10 @@
 #define TARGET_ADDRESS_COST default_address_cost
 #define TARGET_CONST_ANCHOR 0
 
+#ifndef TARGET_MEMORY_MOVE_COST
+#define TARGET_MEMORY_MOVE_COST default_memory_move_cost
+#endif
+
 /* In builtins.c.  */
 #define TARGET_INIT_BUILTINS hook_void_void
 #define TARGET_EXPAND_BUILTIN default_expand_builtin
@@ -1002,6 +1006,7 @@
   TARGET_ADDR_SPACE_HOOKS,                     \
   TARGET_SCALAR_MODE_SUPPORTED_P,              \
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
+  TARGET_MEMORY_MOVE_COST,                     \
   TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P,    \
   TARGET_RTX_COSTS,                            \
   TARGET_ADDRESS_COST,                         \
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c       (revision 160046)
+++ gcc/reginfo.c       (working copy)
@@ -681,12 +681,18 @@
     top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx);
 }
 
+/* Compute cost of moving registers to/from memory.  */
+int
+memory_move_cost (enum machine_mode mode, enum reg_class rclass, bool in)
+{
+  return targetm.memory_move_cost (mode, rclass, in);
+}
 
 /* Compute extra cost of moving registers to/from memory due to reloads.
    Only needed if secondary reloads are required for memory moves.  */
 int
 memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass,
-                           int in)
+                           bool in)
 {
   enum reg_class altclass;
   int partial_cost = 0;
@@ -706,8 +712,8 @@
 
   if (rclass == altclass)
     /* This isn't simply a copy-to-temporary situation.  Can't guess
-       what it is, so MEMORY_MOVE_COST really ought not to be calling
-       here in that case.
+       what it is, so TARGET_MEMORY_MOVE_COST really ought not to be
+       calling here in that case.
 
        I'm tempted to put in an assert here, but returning this will
        probably only give poor estimates, which is what we would've
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h      (revision 160046)
+++ gcc/config/i386/i386.h      (working copy)
@@ -1903,17 +1903,6 @@
 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
    ix86_register_move_cost ((MODE), (CLASS1), (CLASS2))
 
-/* A C expression for the cost of moving data of mode M between a
-   register and memory.  A value of 2 is the default; this cost is
-   relative to those in `REGISTER_MOVE_COST'.
-
-   If moving between registers and memory is more expensive than
-   between two registers, you should define this macro to express the
-   relative cost.  */
-
-#define MEMORY_MOVE_COST(MODE, CLASS, IN)      \
-  ix86_memory_move_cost ((MODE), (CLASS), (IN))
-
 /* 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 160046)
+++ gcc/config/i386/i386-protos.h       (working copy)
@@ -158,7 +158,6 @@
                                           enum machine_mode, enum reg_class);
 extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
 extern enum reg_class ix86_preferred_output_reload_class (rtx, enum reg_class);
-extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
 extern int ix86_mode_needed (int, rtx);
 extern void emit_i387_cw_initialization (int);
 extern void x86_order_regs_for_local_alloc (void);
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 160046)
+++ gcc/config/i386/i386.c      (working copy)
@@ -25570,10 +25570,11 @@
     }
 }
 
-int
-ix86_memory_move_cost (enum machine_mode mode, enum reg_class regclass, int in)
+static int
+ix86_memory_move_cost (enum machine_mode mode, enum reg_class regclass,
+                      bool in)
 {
-  return inline_memory_move_cost (mode, regclass, in);
+  return inline_memory_move_cost (mode, regclass, in ? 1 : 0);
 }
 
 
@@ -30725,6 +30726,8 @@
 #undef TARGET_HANDLE_OPTION
 #define TARGET_HANDLE_OPTION ix86_handle_option
 
+#undef TARGET_MEMORY_MOVE_COST
+#define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS ix86_rtx_costs
 #undef TARGET_ADDRESS_COST
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c       (revision 160046)
+++ gcc/reload1.c       (working copy)
@@ -6168,7 +6168,7 @@
                             if copying it to the desired class is cheap
                             enough.  */
                          || ((REGISTER_MOVE_COST (mode, last_class, rclass)
-                              < MEMORY_MOVE_COST (mode, rclass, 1))
+                              < memory_move_cost (mode, rclass, true))
                              && (secondary_reload_class (1, rclass, mode,
                                                          last_reg)
                                  == NO_REGS)


Anatoly.



More information about the Gcc-patches mailing list