As mentioned in PR65768, ARM gcc generates suboptimal code for constant
Uses in loop. Part of the reason is cprop is undoing what loop invariant
code motion did.

Zhenqiang posted a patch at to fix this based on rtx costs:
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01321.html

I cleaned it up and bootstrapped, regression tested on x86_64-linux-gnu;
no new regressions. Is this OK for trunk?

Thanks,
Kugan

gcc/ChangeLog:

2015-04-15  Kugan Vivekanandarajah  <kug...@linaro.org>
            Zhenqiang Chen  <zhenqiang.c...@linaro.org>

        PR target/65768
        * cprop.c (try_replace_reg): Check cost of constants before propagating.
diff --git a/gcc/cprop.c b/gcc/cprop.c
index c9fb2fc..42a2a72 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -758,12 +758,38 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn)
   int success = 0;
   rtx set = single_set (insn);
 
+  bool already_const_p = false;
+  bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
+  int old_cost = set ? set_rtx_cost (set, speed) : 0;
+
+  if ((note != 0
+      && REG_NOTE_KIND (note) == REG_EQUAL
+      && (GET_CODE (XEXP (note, 0)) == CONST
+         || CONSTANT_P (XEXP (note, 0))))
+      || (set && CONSTANT_P (SET_SRC (set))))
+    already_const_p = true;
+
   /* Usually we substitute easy stuff, so we won't copy everything.
      We however need to take care to not duplicate non-trivial CONST
      expressions.  */
   to = copy_rtx (to);
 
   validate_replace_src_group (from, to, insn);
+
+
+  /* For CONSTANT_P (to), loop2_invariant pass might hoist it out the loop.
+     And it can be shared by different references.  So skip propagation if
+     it makes INSN's rtx cost higher.  */
+
+  if (!already_const_p
+      && CONSTANT_P (to)
+      && (set_rtx_cost (set, speed) > old_cost))
+    {
+      cancel_changes (0);
+      return false;
+    }
+
+
   if (num_changes_pending () && apply_change_group ())
     success = 1;
 

Reply via email to