From d6220b11a7d208c4713bd4da4bbec792a25ffde9 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Fri, 19 Dec 2014 04:40:11 +0000 Subject: [PATCH] * Add TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV target macro. From-SVN: r218886 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/sh/sh.c | 22 ++++++++++++++++++++++ gcc/doc/tm.texi | 10 ++++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/lra-constraints.c | 6 +++++- gcc/target.def | 14 ++++++++++++++ 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d83cad..315496c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2014-12-19 Kaz Kojima + * lra-constraints.c (get_equiv): Don't return memory equivalence + when targetm.cannot_substitute_mem_equiv_p is true. + * target.def (cannot_substitute_mem_equiv_p): New hook. + * config/sh/sh.c (sh_cannot_substitute_mem_equiv_p): New function. + (TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P): Define. + * doc/tm.texi.in (TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P): New hook. + * doc/tm.texi: Regenerate. + +2014-12-19 Kaz Kojima + * lra-constraints.c (process_address_1): Swap base_term and index_term if INDEX_REG_CLASS is assigned to base_term already when INDEX_REG_CLASS is a single register class. diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index b89d048..eb19c42 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -291,6 +291,7 @@ static reg_class_t sh_secondary_reload (bool, rtx, reg_class_t, static bool sh_legitimate_address_p (machine_mode, rtx, bool); static rtx sh_legitimize_address (rtx, rtx, machine_mode); static rtx sh_delegitimize_address (rtx); +static bool sh_cannot_substitute_mem_equiv_p (rtx); static int shmedia_target_regs_stack_space (HARD_REG_SET *); static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *); static int shmedia_target_regs_stack_adjust (HARD_REG_SET *); @@ -630,6 +631,9 @@ static const struct attribute_spec sh_attribute_table[] = #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P sh_legitimate_address_p +#undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P +#define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P sh_cannot_substitute_mem_equiv_p + #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT sh_trampoline_init #undef TARGET_TRAMPOLINE_ADJUST_ADDRESS @@ -13214,6 +13218,24 @@ sh_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +/* Return true if SUBST can't safely replace its equivalent during RA. */ +static bool +sh_cannot_substitute_mem_equiv_p (rtx) +{ + if (TARGET_SHMEDIA) + return false; + + /* If SUBST is mem[base+index] or QI/HImode mem[base+disp], the insn + uses R0 and may cause spill failure when R0 is already used. + We have to return true for that case at least. + Moreover SH has strong R0 parity and also have not enough numbers of + the hard registers to make the equiv substitution win in the size + and the speed on average working sets. The pseudos produced to + hold the equiv values can't get good hard registers for bad cases + and end up memory save/restore insns which make the code worse. */ + return true; +} + static void sh_conditional_register_usage (void) { diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ee741a9..50e80f6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2847,6 +2847,16 @@ A target hook which returns true if we need register usage leveling. That means A target hook which returns true if an address with the same structure can have different maximal legitimate displacement. For example, the displacement can depend on memory mode or on operand combinations in the insn. The default version of this target hook returns always false. @end deftypefn +@deftypefn {Target Hook} bool TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P (rtx @var{subst}) +A target hook which returns @code{true} if @var{subst} can't +substitute safely pseudos with equivalent memory values during +register allocation. +The default version of this target hook returns @code{false}. +On most machines, this default should be used. For generally +machines with non orthogonal register usage for addressing, such +as SH, this hook can be used to avoid excessive spilling. +@end deftypefn + @deftypefn {Target Hook} reg_class_t TARGET_SPILL_CLASS (reg_class_t, @var{machine_mode}) This hook defines a class of registers which could be used for spilling pseudos of the given mode and class, or @code{NO_REGS} if only memory should be used. Not defining this hook is equivalent to returning @code{NO_REGS} for all inputs. @end deftypefn diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 8f86538..a99cc72 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2481,6 +2481,8 @@ as below: @hook TARGET_DIFFERENT_ADDR_DISPLACEMENT_P +@hook TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P + @hook TARGET_SPILL_CLASS @hook TARGET_CSTORE_MODE diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 8fc2cb7..9e9539c 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -488,7 +488,11 @@ get_equiv (rtx x) || lra_get_regno_hard_regno (regno) >= 0) return x; if ((res = ira_reg_equiv[regno].memory) != NULL_RTX) - return res; + { + if (targetm.cannot_substitute_mem_equiv_p (res)) + return x; + return res; + } if ((res = ira_reg_equiv[regno].constant) != NULL_RTX) return res; if ((res = ira_reg_equiv[regno].invariant) != NULL_RTX) diff --git a/gcc/target.def b/gcc/target.def index e7cec46..a380381 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5037,6 +5037,20 @@ DEFHOOK reg_class_t, (reg_class_t rclass), default_preferred_rename_class) +/* This target hook allows the backend to avoid unsafe substitution + during register allocation. */ +DEFHOOK +(cannot_substitute_mem_equiv_p, + "A target hook which returns @code{true} if @var{subst} can't\n\ +substitute safely pseudos with equivalent memory values during\n\ +register allocation.\n\ +The default version of this target hook returns @code{false}.\n\ +On most machines, this default should be used. For generally\n\ +machines with non orthogonal register usage for addressing, such\n\ +as SH, this hook can be used to avoid excessive spilling.", + bool, (rtx subst), + hook_bool_rtx_false) + /* This target hook allows the backend to perform additional processing while initializing for variable expansion. */ DEFHOOK -- 2.7.4