aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatoly Sokolov <aesok@post.ru>2010-06-05 17:27:51 +0000
committerAnatoly Sokolov <aesok@post.ru>2010-06-05 17:27:51 +0000
commitff618de8bfea4333be2910a4e47357f29d9f82ee (patch)
tree5acbb363779f56a111143ed54e7f8d18e54e8448
parent053d4f2b9eb9c2d65154251678a37b2e80b9cbeb (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@160323 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c9
-rw-r--r--gcc/config/i386/i386.h11
-rw-r--r--gcc/doc/tm.texi27
-rw-r--r--gcc/ira.c13
-rw-r--r--gcc/ira.h2
-rw-r--r--gcc/postreload.c2
-rw-r--r--gcc/reginfo.c12
-rw-r--r--gcc/reload.h9
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/target-def.h5
-rw-r--r--gcc/target.h3
-rw-r--r--gcc/targhooks.c14
-rw-r--r--gcc/targhooks.h1
15 files changed, 104 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 85b61fe0bee..eff2a56dd45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2010-06-05 Anatoly Sokolov <aesok@post.ru>
+
+ * 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.
+
2010-06-05 Jan Hubicka <jh@suse.cz>
* ipa-pure-const.c (propagate): Fix type in handling functions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 33893da247c..5bd8749645e 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -157,7 +157,6 @@ extern bool ix86_cannot_change_mode_class (enum machine_mode,
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);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ea9aae3612d..2a46f89cb24 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -25580,10 +25580,11 @@ inline_memory_move_cost (enum machine_mode mode, enum reg_class regclass,
}
}
-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);
}
@@ -30742,6 +30743,8 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 5e8fcadfe45..c3fc0e436db 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1903,17 +1903,6 @@ do { \
#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. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6e68d2ea8d3..16a30a866dc 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6178,8 +6178,35 @@ secondary register in the conventional way but the default base value of
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}
diff --git a/gcc/ira.c b/gcc/ira.c
index 4fac13ce994..843095dbb93 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -358,9 +358,10 @@ HARD_REG_SET eliminable_regset;
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 @@ setup_class_subset_and_memory_move_costs (void)
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. */
diff --git a/gcc/ira.h b/gcc/ira.h
index 97bfa875012..12b4b42017a 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -58,7 +58,7 @@ extern HARD_REG_SET ira_no_alloc_regs;
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
diff --git a/gcc/postreload.c b/gcc/postreload.c
index a03cdfacee3..c165b5245f1 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -262,7 +262,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
/* 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);
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 4cfcf843a05..66e774a30c2 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -681,12 +681,18 @@ init_fake_stack_mems (void)
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 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass,
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
diff --git a/gcc/reload.h b/gcc/reload.h
index 8168b51f020..4625bf7fc19 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -30,12 +30,9 @@ along with GCC; see the file COPYING3. If not see
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))
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 030d0078203..f3d61c66a98 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -6501,7 +6501,7 @@ choose_reload_regs (struct insn_chain *chain)
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)
diff --git a/gcc/target-def.h b/gcc/target-def.h
index b91a000e7c7..5a088bcd4dc 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -468,6 +468,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
@@ -1017,6 +1021,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, \
diff --git a/gcc/target.h b/gcc/target.h
index c8be2b5a46c..4e2bf984cb1 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -791,6 +791,9 @@ struct gcc_target
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
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index f6dbebf5310..3dccae267f7 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1088,4 +1088,18 @@ default_have_conditional_execution (void)
#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"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index f6be95dff87..efc8a981c68 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -137,3 +137,4 @@ extern bool default_addr_space_subset_p (addr_space_t, addr_space_t);
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);