]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/97623 - Avoid PRE hoist insertion iteration
authorRichard Biener <rguenther@suse.de>
Tue, 3 Nov 2020 14:03:41 +0000 (15:03 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 11 Jan 2021 13:36:07 +0000 (14:36 +0100)
We are not really interested in PRE opportunities exposed by
hoisting but only the other way around.  So this moves hoist
insertion after PRE iteration finished and removes hoist
insertion iteration alltogether.

It also guards access to NEW_SETS properly.

2020-11-11  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97623
* tree-ssa-pre.c (insert): Move hoist insertion after PRE
insertion iteration and do not iterate it.
(create_expression_by_pieces): Guard NEW_SETS access.
(insert_into_preds_of_block): Likewise.

* gcc.dg/tree-ssa/ssa-hoist-3.c: Adjust.
* gcc.dg/tree-ssa/ssa-hoist-7.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.

gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
gcc/tree-ssa-pre.c

index 51ba59c9ab6b39430177c91a779228a5154c46ce..de3051bfb50c055bc91431d9fb2b9a89e1eff945 100644 (file)
@@ -15,4 +15,4 @@ int test (int a, int b, int c, int g)
 /* We should hoist and CSE only the multiplication.  */
 
 /* { dg-final { scan-tree-dump-times " \\* " 1 "pre" } } */
-/* { dg-final { scan-tree-dump "Insertions: 1" "pre" } } */
+/* { dg-final { scan-tree-dump "HOIST inserted: 1" "pre" } } */
index ce9cec61668a4ba6b6b3b74488732806aea7b1b3..fdb6a3ed349902c3f51a0b91d665f645ccc5b8b6 100644 (file)
@@ -49,6 +49,6 @@ void foo (int a, int b, int c, int d, int e, int x, int y, int z)
 
 /* 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" } } */
+   we do not iterate PRE insertion.  */
+/* { dg-final { scan-tree-dump "insert iterations == 1" "pre" } } */
 /* { dg-final { scan-tree-dump "HOIST inserted: 5" "pre" } } */
index 59af63ad5aca696b42cdbddf3d32a84f527683e5..cf9317372d64f91df9e851fe3d61db3bd6b44b83 100644 (file)
@@ -24,4 +24,4 @@ bar (int b, int x)
 /* We should see the partial redundant loads of f even though they
    are using different types (of the same size).  */
 
-/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */
+/* { dg-final { scan-tree-dump-times "Replaced MEM" 3 "pre" } } */
index 8776805f5dbba1f043062e31e4fc1d9a65453165..465f843fdc023de6d39452e4a61c9512501164fb 100644 (file)
@@ -2953,7 +2953,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
              VN_INFO (forcedname)->value_id = get_next_value_id ();
              nameexpr = get_or_alloc_expr_for_name (forcedname);
              add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
-             bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
+             if (NEW_SETS (block))
+               bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
              bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
            }
 
@@ -3118,8 +3119,8 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
   bitmap_insert_into_set (PHI_GEN (block), newphi);
   bitmap_value_replace_in_set (AVAIL_OUT (block),
                               newphi);
-  bitmap_insert_into_set (NEW_SETS (block),
-                         newphi);
+  if (NEW_SETS (block))
+    bitmap_insert_into_set (NEW_SETS (block), newphi);
 
   /* If we insert a PHI node for a conversion of another PHI node
      in the same basic-block try to preserve range information.
@@ -3645,15 +3646,6 @@ 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]);
@@ -3701,6 +3693,28 @@ insert (void)
 
   statistics_histogram_event (cfun, "insert iterations", num_iterations);
 
+  /* AVAIL_OUT is not needed after insertion so we don't have to
+     propagate NEW_SETS from hoist insertion.  */
+  FOR_ALL_BB_FN (bb, cfun)
+    {
+      bitmap_set_pool.remove (NEW_SETS (bb));
+      NEW_SETS (bb) = NULL;
+    }
+
+  /* Insert expressions for hoisting.  Do a backward walk here since
+     inserting into BLOCK exposes new opportunities in its predecessors.
+     Since PRE and hoist insertions can cause back-to-back iteration
+     and we are interested in PRE insertion exposed hoisting opportunities
+     but not in hoisting exposed PRE ones do hoist insertion only after
+     PRE insertion iteration finished and do not iterate it.  */
+  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);
+      }
+
   free (rpo);
 }