From e6078fbbeb7c0b6152faed2a1c070fdb3fb016b9 Mon Sep 17 00:00:00 2001 From: aesok Date: Sun, 27 Jun 2010 11:40:42 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161470 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 32 ++++++++++++++++++++++++++++++++ gcc/config/i386/i386-protos.h | 2 -- gcc/config/i386/i386.c | 4 +++- gcc/config/i386/i386.h | 11 ----------- gcc/config/ia64/ia64-protos.h | 2 -- gcc/config/ia64/ia64.c | 6 +++++- gcc/config/ia64/ia64.h | 5 ----- gcc/defaults.h | 4 ---- gcc/doc/md.texi | 3 ++- gcc/doc/tm.texi | 30 +++++++++++++++++++++++++++--- gcc/ira-int.h | 2 +- gcc/ira.c | 2 +- gcc/postreload.c | 4 ++-- gcc/reginfo.c | 19 +++++++++++++++---- gcc/reload.c | 6 +++--- gcc/reload.h | 2 ++ gcc/reload1.c | 2 +- gcc/target-def.h | 5 +++++ gcc/target.h | 5 +++++ gcc/targhooks.c | 15 +++++++++++++++ gcc/targhooks.h | 3 +++ 21 files changed, 122 insertions(+), 42 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a6908c..4a1fe90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2010-06-27 Anatoly Sokolov + + * 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 PR tree-optimization/44683 diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 5bd8749..308f9ee 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -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, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e0d8dc4..bd1cc05 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 226f784..67f1f60 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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. */ diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index cd89e7c..a5914b1 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -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); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 4d6dbde..d40747a 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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) { diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 8192b9f..bf24f73 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -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) \ diff --git a/gcc/defaults.h b/gcc/defaults.h index c4809c9..eb74033 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -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 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 46bd4f6..211fdcb 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -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 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c001c8b..637dd50 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/ira-int.h b/gcc/ira-int.h index fd5ffb8..1da087c 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -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]; diff --git a/gcc/ira.c b/gcc/ira.c index a2e8c38..7f4c8d8 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -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 diff --git a/gcc/postreload.c b/gcc/postreload.c index c165b52..3882719 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -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); } diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 66e774a..b868c37 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -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 diff --git a/gcc/reload.c b/gcc/reload.c index d4b7982..30bee6d 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -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; diff --git a/gcc/reload.h b/gcc/reload.h index 4625bf7..a3c1f07 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -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); diff --git a/gcc/reload1.c b/gcc/reload1.c index 00d4c99..a0b61f5 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -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) diff --git a/gcc/target-def.h b/gcc/target-def.h index 1aaf38c..27b7fa8 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -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, \ diff --git a/gcc/target.h b/gcc/target.h index 2f181eb..5a857d7 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -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); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 6c1d258..62e3577 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -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" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 6e71445..fdd0e4a 100644 --- a/gcc/targhooks.h +++ b/gcc/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); + -- 2.7.4