re PR tree-optimization/77283 (Revision 238005 disables loop unrolling)
authorRichard Biener <rguenther@suse.de>
Fri, 13 Jan 2017 08:11:01 +0000 (08:11 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 13 Jan 2017 08:11:01 +0000 (08:11 +0000)
2017-01-13  Richard Biener  <rguenther@suse.de>

PR tree-optimization/77283
* gimple-ssa-split-paths.c: Include gimple-ssa.h, tree-phinodes.h
and ssa-iterators.h.
(is_feasible_trace): Implement a cost model based on joiner
PHI node uses.

* gcc.dg/tree-ssa/split-path-7.c: Adjust.
* gcc.dg/tree-ssa/split-path-8.c: New testcase.
* gcc.dg/tree-ssa/split-path-9.c: Likewise.

From-SVN: r244392

gcc/gimple-ssa-split-paths.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c [new file with mode: 0644]

index ef6c7203f6bcae6259b53c64d40e1029d4ab8bb4..f1bf7ec604c0d0ce41cc329ab36c7267040c2e04 100644 (file)
@@ -32,6 +32,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "tracer.h"
 #include "predict.h"
 #include "params.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
 
 /* Given LATCH, the latch block in a loop, see if the shape of the
    path reaching LATCH is suitable for being split by duplication.
@@ -200,6 +203,58 @@ is_feasible_trace (basic_block bb)
        }
     }
 
+  /* If the joiner has no PHIs with useful uses there is zero chance
+     of CSE/DCE/jump-threading possibilities exposed by duplicating it.  */
+  bool found_useful_phi = false;
+  for (gphi_iterator si = gsi_start_phis (bb); ! gsi_end_p (si);
+       gsi_next (&si))
+    {
+      gphi *phi = si.phi ();
+      use_operand_p use_p;
+      imm_use_iterator iter;
+      FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
+       {
+         gimple *stmt = USE_STMT (use_p);
+         if (is_gimple_debug (stmt))
+           continue;
+         /* If there's a use in the joiner this might be a CSE/DCE
+            opportunity.  */
+         if (gimple_bb (stmt) == bb)
+           {
+             found_useful_phi = true;
+             break;
+           }
+         /* If the use is on a loop header PHI and on one path the
+            value is unchanged this might expose a jump threading
+            opportunity.  */
+         if (gimple_code (stmt) == GIMPLE_PHI
+             && gimple_bb (stmt) == bb->loop_father->header
+             /* But for memory the PHI alone isn't good enough.  */
+             && ! virtual_operand_p (gimple_phi_result (stmt)))
+           {
+             for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
+               if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
+                 {
+                   found_useful_phi = true;
+                   break;
+                 }
+             if (found_useful_phi)
+               break;
+           }
+       }
+      if (found_useful_phi)
+       break;
+    }
+  if (! found_useful_phi)
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file,
+                "Block %d is a join that does not expose CSE/DCE/jump-thread "
+                "opportunities when duplicated.\n",
+                bb->index);
+      return false;
+    }
+
   /* We may want something here which looks at dataflow and tries
      to guess if duplication of BB is likely to result in simplification
      of instructions in BB in either the original or the duplicate.  */
index d8fa57c146996cd5a9216d8066037ca4a6b78745..4dc4fc1109fbe750762573d86a662439332372a3 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-13  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/77283
+       * gcc.dg/tree-ssa/split-path-7.c: Adjust.
+       * gcc.dg/tree-ssa/split-path-8.c: New testcase.
+       * gcc.dg/tree-ssa/split-path-9.c: Likewise.
+
 2017-01-12  Sandra Loosemore  <sandra@codesourcery.com>
 
        * gcc.dg/pr77862.c: Require fpic target.
index f14ab7929bdeeeeb0c82b722ef44727e5262363c..f80d30655e718d326975beb4f1461c1eaeeecc89 100644 (file)
@@ -91,4 +91,4 @@ linit ()
        }
     }
 }
-/* { dg-final { scan-tree-dump-times "Duplicating join block" 2 "split-paths" } } */
+/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c
new file mode 100644 (file)
index 0000000..fb54f5d
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR77283 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
+
+void
+foo (double *x, double *a, double *b, long n, double limit)
+{
+  long i;
+  for (i=0; i < n; i++)
+    if (a[i] < limit)
+      x[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c
new file mode 100644 (file)
index 0000000..bd4ee76
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR77366 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
+
+void
+foo(unsigned int size, unsigned int *state)
+{
+  unsigned int i;
+
+  for(i = 0; i < size; i++)
+    {
+      if(*state & 1)
+       *state ^= 1;
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" } } */