tree-optimization/98213 - cache PHI walking result in SM
authorRichard Biener <rguenther@suse.de>
Wed, 9 Dec 2020 14:48:36 +0000 (15:48 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 9 Dec 2020 16:27:25 +0000 (17:27 +0100)
This avoids exponential work when walking PHIs in loop store motion.
Fails are quickly propagated and thus need no caching.

2020-12-09  Richard Biener  <rguenther@suse.de>

PR tree-optimization/98213
* tree-ssa-loop-im.c (sm_seq_valid_bb): Cache successfully
processed PHIs.
(hoist_memory_references): Adjust.

* g++.dg/pr98213.C: New testcase.

gcc/testsuite/g++.dg/pr98213.C [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

diff --git a/gcc/testsuite/g++.dg/pr98213.C b/gcc/testsuite/g++.dg/pr98213.C
new file mode 100644 (file)
index 0000000..1a744eb
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <algorithm>
+
+long var_23;
+int var_24, test_var_8;
+extern bool arr_20[][13];
+char arr_21_0_0_0_0_0;
+int *test_arr_0;
+void test(unsigned long long var_1)
+{
+  int arr_16;
+  for (int i_0 = 0;;)
+    for (int i_5; i_5;) {
+      for (int i_6 = 0; i_6 < 19; i_6 += 4)
+        for (long i_7(test_var_8); i_7; i_7 += 2) {
+          arr_20[0][i_7] = arr_21_0_0_0_0_0 = 0;
+          var_23 = test_arr_0[0];
+        }
+      var_24 = std::max((unsigned long long)arr_16,
+                        std::min((unsigned long long)5, var_1));
+    }
+}
index 92e5a8dd7742f24f83b942ff5eb4958ef9289adc..fe48d02242d546f8035b3d62242550faabbc84ff 100644 (file)
@@ -2254,7 +2254,8 @@ sm_seq_push_down (vec<seq_entry> &seq, unsigned ptr, unsigned *at)
 static int
 sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
                 vec<seq_entry> &seq, bitmap refs_not_in_seq,
-                bitmap refs_not_supported, bool forked)
+                bitmap refs_not_supported, bool forked,
+                bitmap fully_visited)
 {
   if (!vdef)
     for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
@@ -2276,7 +2277,7 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
        /* This handles the perfect nest case.  */
        return sm_seq_valid_bb (loop, single_pred (bb), vdef,
                                seq, refs_not_in_seq, refs_not_supported,
-                               forked);
+                               forked, fully_visited);
       return 0;
     }
   do
@@ -2314,7 +2315,10 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
            return sm_seq_valid_bb (loop, gimple_phi_arg_edge (phi, 0)->src,
                                    gimple_phi_arg_def (phi, 0), seq,
                                    refs_not_in_seq, refs_not_supported,
-                                   false);
+                                   false, fully_visited);
+         if (bitmap_bit_p (fully_visited,
+                           SSA_NAME_VERSION (gimple_phi_result (phi))))
+           return 1;
          auto_vec<seq_entry> first_edge_seq;
          auto_bitmap tem_refs_not_in_seq (&lim_bitmap_obstack);
          int eret;
@@ -2323,7 +2327,7 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
                                  gimple_phi_arg_def (phi, 0),
                                  first_edge_seq,
                                  tem_refs_not_in_seq, refs_not_supported,
-                                 true);
+                                 true, fully_visited);
          if (eret != 1)
            return -1;
          /* Simplify our lives by pruning the sequence of !sm_ord.  */
@@ -2338,7 +2342,7 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
              bitmap_copy (tem_refs_not_in_seq, refs_not_in_seq);
              eret = sm_seq_valid_bb (loop, e->src, vuse, edge_seq,
                                      tem_refs_not_in_seq, refs_not_supported,
-                                     true);
+                                     true, fully_visited);
              if (eret != 1)
                return -1;
              /* Simplify our lives by pruning the sequence of !sm_ord.  */
@@ -2419,6 +2423,8 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
                  seq[new_idx].from = NULL_TREE;
                }
            }
+         bitmap_set_bit (fully_visited,
+                         SSA_NAME_VERSION (gimple_phi_result (phi)));
          return 1;
        }
       lim_aux_data *data = get_lim_data (def);
@@ -2494,9 +2500,11 @@ hoist_memory_references (class loop *loop, bitmap mem_refs,
       seq.create (4);
       auto_bitmap refs_not_in_seq (&lim_bitmap_obstack);
       bitmap_copy (refs_not_in_seq, mem_refs);
+      auto_bitmap fully_visited;
       int res = sm_seq_valid_bb (loop, e->src, NULL_TREE,
                                 seq, refs_not_in_seq,
-                                refs_not_supported, false);
+                                refs_not_supported, false,
+                                fully_visited);
       if (res != 1)
        {
          bitmap_copy (refs_not_supported, mem_refs);