]> gcc.gnu.org Git - gcc.git/commitdiff
Improve LIM fill_always_executed_in computation
authorRichard Biener <rguenther@suse.de>
Thu, 9 Sep 2021 09:50:20 +0000 (11:50 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 9 Sep 2021 09:50:20 +0000 (11:50 +0200)
Currently the DOM walk over a loop body does not walk into not
always executed subloops to avoid scalability issues since doing
so makes the walk quadratic in the loop depth.  It turns out this
is not an issue in practice and even with a loop depth of 1800
this function is way off the radar.

So the following patch removes the limitation, replacing it with
a comment.

2021-09-09  Richard Biener  <rguenther@suse.de>

* tree-ssa-loop-im.c (fill_always_executed_in_1): Walk
into all subloops.

* gcc.dg/tree-ssa/ssa-lim-17.c: New testcase.

gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c
new file mode 100644 (file)
index 0000000..1c840e5
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim2-details" } */
+
+volatile int flag, bar;
+double foo (double *valp)
+{
+  double sum = 0;
+  for (int i = 0; i < 256; ++i)
+    {
+      if (flag)
+       for (int j = 0; j < 256; ++j)
+         bar = flag;
+      if (flag)
+        sum += 1.;
+      sum += *valp; // we should move the load of *valp out of the loop
+    }
+  return sum;
+}
+
+/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */
index 5d6845478e76c70cc3f2baec06d59a37b53902c2..4b187c2cdafe586fe159343c1f5b22abfde7446a 100644 (file)
@@ -3074,15 +3074,13 @@ fill_always_executed_in_1 (class loop *loop, sbitmap contains_call)
            break;
 
          if (bb->loop_father->header == bb)
-           {
-             if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
-               break;
-
-             /* In a loop that is always entered we may proceed anyway.
-                But record that we entered it and stop once we leave it
-                since it might not be finite.  */
-             inn_loop = bb->loop_father;
-           }
+           /* Record that we enter into a subloop since it might not
+              be finite.  */
+           /* ???  Entering into a not always executed subloop makes
+              fill_always_executed_in quadratic in loop depth since
+              we walk those loops N times.  This is not a problem
+              in practice though, see PR102253 for a worst-case testcase.  */
+           inn_loop = bb->loop_father;
 
          /* Walk the body of LOOP sorted by dominance relation.  Additionally,
             if a basic block S dominates the latch, then only blocks dominated
This page took 0.076288 seconds and 5 git commands to generate.