* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161470
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-06-27 Anatoly Sokolov <aesok@post.ru>
+
+ * 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.
+
2010-06-27 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44683
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,
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)
{
#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
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
\f
-/* 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. */
extern void ia64_start_function (FILE *, const char *, 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);
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 *);
#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
/* 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)
{
\f
/* 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) \
#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
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
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
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
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];
/* 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
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);
}
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);
}
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
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);
}
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)
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
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))
{
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);
}
}
&& 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;
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);
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)
#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
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, \
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);
#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"
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);
+