tree-optimization/97623 - avoid excessive insert iteration for hoisting
authorRichard Biener <rguenther@suse.de>
Fri, 30 Oct 2020 12:32:32 +0000 (13:32 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 30 Oct 2020 12:35:24 +0000 (13:35 +0100)
This avoids requiring insert iteration for back-to-back hoisting
opportunities as seen in the added testcase.  For the PR at hand
this halves the number of insert iterations retaining only
the hard to avoid PRE / hoist insert back-to-backs.

2020-10-30  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97623
* tree-ssa-pre.c (insert): First do hoist insertion in
a backward walk.

* gcc.dg/tree-ssa/ssa-hoist-7.c: New testcase.

gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
new file mode 100644 (file)
index 0000000..ce9cec6
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+
+void baz();
+int tem;
+void foo (int a, int b, int c, int d, int e, int x, int y, int z)
+{
+  if (a)
+    {
+      if (b)
+        {
+          if (c)
+            {
+             if (d)
+               {
+                 if (e)
+                   {
+                     tem = x + y;
+                   }
+                 else
+                   {
+                     if (z) baz ();
+                     tem = x + y;
+                   }
+               }
+             else
+               {
+                 if (z) baz ();
+                 tem = x + y;
+               }
+           }
+          else
+            {
+              if (z) baz ();
+              tem = x + y;
+            }
+        }
+      else
+        {
+          if (z) baz ();
+          tem = x + y;
+        }
+    }
+  else
+    {
+      if (z) baz ();
+      tem = x + y;
+    }
+}
+
+/* Now inserting x + y five times is unnecessary but the cascading
+   cannot be avoided with the simple-minded dataflow.  But make sure
+   we do the insertions all in the first iteration.  */
+/* { dg-final { scan-tree-dump "insert iterations == 2" "pre" } } */
+/* { dg-final { scan-tree-dump "HOIST inserted: 5" "pre" } } */
index bcef9720095473a0236de95a03716d8bc7ae78a3..091ecb39bb67d7726beedaac9711f84e00eb0779 100644 (file)
@@ -3646,6 +3646,15 @@ insert (void)
        fprintf (dump_file, "Starting insert iteration %d\n", num_iterations);
 
       changed = false;
+      /* Insert expressions for hoisting.  Do a backward walk here since
+        inserting into BLOCK exposes new opportunities in its predecessors.  */
+      if (flag_code_hoisting)
+       for (int idx = rpo_num - 1; idx >= 0; --idx)
+         {
+           basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
+           if (EDGE_COUNT (block->succs) >= 2)
+             changed |= do_hoist_insertion (block);
+         }
       for (int idx = 0; idx < rpo_num; ++idx)
        {
          basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
@@ -3680,10 +3689,6 @@ insert (void)
                  if (do_partial_partial)
                    changed |= do_pre_partial_partial_insertion (block, dom);
                }
-
-             /* Insert expressions for hoisting.  */
-             if (flag_code_hoisting && EDGE_COUNT (block->succs) >= 2)
-               changed |= do_hoist_insertion (block);
            }
        }