loop-invariant.c (struct invariant): Add a new member: eqno;
authorZhenqiang Chen <zhenqiang.chen@linaro.org>
Thu, 3 Jul 2014 05:24:12 +0000 (05:24 +0000)
committerZhenqiang Chen <zqchen@gcc.gnu.org>
Thu, 3 Jul 2014 05:24:12 +0000 (05:24 +0000)
ChangeLog:
2014-07-03  Zhenqiang Chen  <zhenqiang.chen@linaro.org>

* loop-invariant.c (struct invariant): Add a new member: eqno;
(find_identical_invariants): Update eqno;
(create_new_invariant): Init eqno;
(get_inv_cost): Compute comp_cost with eqno;

testsuite/ChangeLog:
2014-07-03  Zhenqiang Chen  <zhenqiang.chen@linaro.org>

* gcc.target/arm/identical-invariants.c: New test.

From-SVN: r212256

gcc/ChangeLog
gcc/loop-invariant.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/identical-invariants.c [new file with mode: 0644]

index 1aec9adcc958b75d59f095c3e04ff34e2be3d0e5..b8511a1adc6906546b1480403205a212367bd7ce 100644 (file)
@@ -1,3 +1,10 @@
+2014-07-03  Zhenqiang Chen  <zhenqiang.chen@linaro.org>
+
+       * loop-invariant.c (struct invariant): Add a new member: eqno;
+       (find_identical_invariants): Update eqno;
+       (create_new_invariant): Init eqno;
+       (get_inv_cost): Compute comp_cost with eqno;
+
 2014-07-02  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * genconfig.c (have_rotate_flag, have_rotatert_flag): New variables.
index d47d461bfd7555293618f13d67d7a5b9ef1620f9..bd67eb9b4cdd0da3e41053871adcb9755368172a 100644 (file)
@@ -104,6 +104,9 @@ struct invariant
   /* The number of the invariant with the same value.  */
   unsigned eqto;
 
+  /* The number of invariants which eqto this.  */
+  unsigned eqno;
+
   /* If we moved the invariant out of the loop, the register that contains its
      value.  */
   rtx reg;
@@ -498,6 +501,7 @@ find_identical_invariants (invariant_htab_type *eq, struct invariant *inv)
   struct invariant *dep;
   rtx expr, set;
   enum machine_mode mode;
+  struct invariant *tmp;
 
   if (inv->eqto != ~0u)
     return;
@@ -513,7 +517,12 @@ find_identical_invariants (invariant_htab_type *eq, struct invariant *inv)
   mode = GET_MODE (expr);
   if (mode == VOIDmode)
     mode = GET_MODE (SET_DEST (set));
-  inv->eqto = find_or_insert_inv (eq, expr, mode, inv)->invno;
+
+  tmp = find_or_insert_inv (eq, expr, mode, inv);
+  inv->eqto = tmp->invno;
+
+  if (tmp->invno != inv->invno && inv->always_executed)
+    tmp->eqno++;
 
   if (dump_file && inv->eqto != inv->invno)
     fprintf (dump_file,
@@ -722,6 +731,10 @@ create_new_invariant (struct def *def, rtx insn, bitmap depends_on,
 
   inv->invno = invariants.length ();
   inv->eqto = ~0u;
+
+  /* Itself.  */
+  inv->eqno = 1;
+
   if (def)
     def->invno = inv->invno;
   invariants.safe_push (inv);
@@ -1136,7 +1149,7 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed,
 
   if (!inv->cheap_address
       || inv->def->n_addr_uses < inv->def->n_uses)
-    (*comp_cost) += inv->cost;
+    (*comp_cost) += inv->cost * inv->eqno;
 
 #ifdef STACK_REGS
   {
index 286898309fa25d3588d99c4c7b8de563398c4c82..58dd47b29ca53fc750eea707d81b426d5f2f8019 100644 (file)
@@ -1,3 +1,7 @@
+2014-07-03  Zhenqiang Chen  <zhenqiang.chen@linaro.org>
+
+       * gcc.target/arm/identical-invariants.c: New test.
+
 2014-07-02  Jan Hubicka  <hubicka@ucw.cz>
            Chen Gang <gang.chen.5i5j@gmail.com>
 
diff --git a/gcc/testsuite/gcc.target/arm/identical-invariants.c b/gcc/testsuite/gcc.target/arm/identical-invariants.c
new file mode 100644 (file)
index 0000000..f3c7f86
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { arm_thumb2_ok } } } */
+/* { dg-options "-O2 -fdump-rtl-loop2_invariant " } */
+
+int t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+extern void foo2 (int *, int *, int *, int *, int *, int *);
+extern int foo3 (int, int, int, int, int, int);
+int foo (int a, int b, int c, int d)
+{
+   int i = a;
+
+   for (; i > 0; i += b)
+    {
+      if (a > 0x1234567)
+       foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+      foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+      if (b > 0x1234567)
+       foo2 (&t7, &t2, &t8, &t4, &t5, &t6);
+      foo2 (&t1, &t2, &t3, &t4, &t5, &t6);
+      if (c > 0x1234567)
+       foo2 (&t1, &t9, &t10, &t4, &t5, &t6);
+      t2 = t5 - d;
+    }
+
+ return foo3 (t1, t2, t3, t4, t5, t6);
+}
+
+/* { dg-final { scan-rtl-dump "Decided to move invariant 0" "loop2_invariant" } } */
+/* { dg-final { cleanup-rtl-dump "loop2_invariant" } } */
+