This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, cprop] Check rtx_cost when propagating constant


Hi,

For some large constant, ports like ARM, need one more instructions to
operate it. e.g

#define MASK 0xfe00ff
void maskdata (int * data, int len)
{
   int i = len;
   for (; i > 0; i -= 2)
    {
      data[i] &= MASK;
      data[i + 1] &= MASK;
    }
}

Need two instructions for each AND operation:

    and    r3, r3, #16711935
    bic    r3, r3, #65536

If we keep the MASK in a register, loop2_invariant pass can hoist it
out the loop. And it can be shared by different references.

So the patch skips constant propagation if it makes INSN's cost higher.

Bootstrap and no make check regression on X86-64 and ARM Chrome book.

OK for trunk?

Thanks!
-Zhenqiang

ChangeLog:
2014-06-17  Zhenqiang Chen  <zhenqiang.chen@linaro.org>

        * cprop.c (try_replace_reg): Check cost for constants.

diff --git a/gcc/cprop.c b/gcc/cprop.c
index aef3ee8..c9cf02a 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -733,6 +733,14 @@ try_replace_reg (rtx from, rtx to, rtx insn)
   rtx src = 0;
   int success = 0;
   rtx set = single_set (insn);
+  int old_cost = 0;
+  bool copy_p = false;
+  bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
+
+  if (set && SET_SRC (set) && REG_P (SET_SRC (set)))
+    copy_p = true;
+  else
+    old_cost = set_rtx_cost (set, speed);

   /* Usually we substitute easy stuff, so we won't copy everything.
      We however need to take care to not duplicate non-trivial CONST
@@ -740,6 +748,20 @@ try_replace_reg (rtx from, rtx to, rtx insn)
   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 (set && !copy_p && CONSTANT_P (to))
+    {
+      int new_cost = set_rtx_cost (set, speed);
+      if (new_cost > old_cost)
+       {
+         cancel_changes (0);
+         return false;
+       }
+    }
+
   if (num_changes_pending () && apply_change_group ())
     success = 1;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]