target.h (struct gcc_target): Add register_move_cost field.
* 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. From-SVN: r161470
This commit is contained in:
parent
533e50f6ac
commit
de8f4b07c0
|
@ -1,3 +1,35 @@
|
|||
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
|
||||
|
|
|
@ -149,8 +149,6 @@ extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
|
|||
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,
|
||||
|
|
|
@ -25656,7 +25656,7 @@ ix86_memory_move_cost (enum machine_mode mode, enum reg_class regclass,
|
|||
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)
|
||||
{
|
||||
|
@ -30828,6 +30828,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_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
|
||||
|
|
|
@ -1891,17 +1891,6 @@ do { \
|
|||
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. */
|
||||
|
|
|
@ -82,8 +82,6 @@ extern void ia64_vms_elf_asm_named_section (const char *, unsigned int, tree);
|
|||
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);
|
||||
|
|
|
@ -210,6 +210,8 @@ static bool ia64_return_in_memory (const_tree, const_tree);
|
|||
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 @@ static const struct attribute_spec ia64_attribute_table[] =
|
|||
#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
|
||||
|
@ -5202,7 +5206,7 @@ ia64_rtx_costs (rtx x, int code, int outer_code, int *total,
|
|||
/* 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)
|
||||
{
|
||||
|
|
|
@ -1310,11 +1310,6 @@ do { \
|
|||
|
||||
/* 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) \
|
||||
|
|
|
@ -981,10 +981,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
#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
|
||||
|
|
|
@ -3763,7 +3763,8 @@ it is unsafe to call @code{gen_reg_rtx} to allocate a new pseudo.
|
|||
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
|
||||
|
|
|
@ -6116,8 +6116,32 @@ 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.
|
||||
|
||||
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
|
||||
|
@ -6149,9 +6173,9 @@ These macros are obsolete, new ports should use the target hook
|
|||
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
|
||||
|
|
|
@ -724,7 +724,7 @@ minmax_set_iter_next (minmax_set_iterator *i)
|
|||
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];
|
||||
|
|
|
@ -358,7 +358,7 @@ HARD_REG_SET ira_reg_mode_hard_regset[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
|
|||
/* 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
|
||||
|
|
|
@ -264,7 +264,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
|
|||
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 @@ reload_cse_simplify_set (rtx set, rtx insn)
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ bool have_regs_of_mode [MAX_MACHINE_MODE];
|
|||
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 @@ init_move_cost (enum machine_mode m)
|
|||
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 @@ init_fake_stack_mems (void)
|
|||
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 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass,
|
|||
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
|
||||
|
|
|
@ -688,7 +688,7 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
|
|||
|
||||
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 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
|
|||
{
|
||||
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 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||
&& 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;
|
||||
|
|
|
@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
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);
|
||||
|
|
|
@ -6496,7 +6496,7 @@ choose_reload_regs (struct insn_chain *chain)
|
|||
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)
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -812,6 +812,11 @@ struct gcc_target
|
|||
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);
|
||||
|
||||
|
|
|
@ -1127,4 +1127,19 @@ default_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
|
|||
#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"
|
||||
|
|
|
@ -140,3 +140,6 @@ 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);
|
||||
extern int default_register_move_cost (enum machine_mode, enum reg_class,
|
||||
enum reg_class);
|
||||
|
||||
|
|
Loading…
Reference in New Issue