* Add TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV target macro.
authorKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Dec 2014 04:40:11 +0000 (04:40 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Dec 2014 04:40:11 +0000 (04:40 +0000)
From-SVN: r218886

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/lra-constraints.c
gcc/target.def

index 4d83cadb0ee741d0b60292a88a5f3619c14b3d82..315496c08a82010177c28cbb1878cacffdbd8730 100644 (file)
@@ -1,3 +1,13 @@
+2014-12-19  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * 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  <kkojima@gcc.gnu.org>
 
        * lra-constraints.c (process_address_1): Swap base_term and
index b89d0481fac157e48ee2cd32c861bf4b3d8eab3c..eb19c42894bb81f70ca356f0bece996d402b19ff 100644 (file)
@@ -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)
 {
index ee741a97fc3ea077aae1056c7fe6637678354057..50e80f642263da7ed67f82fb81728e215c0c9f8f 100644 (file)
@@ -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
index 8f865381f164991d3310cac9e52ffcb12145ea2d..a99cc72b2e22d0771f665b7952fdc30719aaa670 100644 (file)
@@ -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
index 8fc2cb77a5d913d015e67b470bc602bfe99cdec5..9e9539c1a845e7eaf3abd64e61eb67fef88592a4 100644 (file)
@@ -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)
index e7cec462e020709ed73876d3406df61930aeacec..a380381695d1b44be5895887eca2aab8d95fa875 100644 (file)
@@ -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