> On 25 April 2023 17:12:50 CEST, Jan Hubicka via Gcc-patches 
> <gcc-patches@gcc.gnu.org> wrote:
> 
> +      fprintf (stderr, "Bingo\n");
> 
> You forgot to remove that..
> Do we prune Bingo in the testsuite? ;-)
Ah, thanks :)
I was curious how much I win with unlooping.
Updated patch is attached...

        * cfgloopmanip.h (unloop_loops): Declare.
        * tree-ssa-loop-ch.cc (ch_base::copy_headers): Unloop loops that
        no longer loop.
        * tree-ssa-loop-ivcanon.cc (unloop_loops): Export; do not release
        vectors passed.
        (canonicalize_induction_variables): Release vectors here.
        (tree_unroll_loops_completely): Release vectors here.

diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
index c40cfeae0e3..75b2a5e9b75 100644
--- a/gcc/cfgloopmanip.h
+++ b/gcc/cfgloopmanip.h
@@ -43,6 +43,10 @@ extern edge create_empty_if_region_on_edge (edge, tree);
 extern class loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
                                               tree *, tree *, class loop *);
 extern void unloop (class loop *, bool *, bitmap);
+extern void unloop_loops (vec<class loop *> &loops_to_unloop,
+                         vec<int> &loops_to_unloop_nunroll,
+                         bitmap loop_closed_ssa_invalidated,
+                         bool *irred_invalidated);
 extern void copy_loop_info (class loop *loop, class loop *target);
 extern class loop * duplicate_loop (class loop *, class loop *,
                                     class loop * = NULL);
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 2fd58db9a2e..05f1dd9b500 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -64,6 +64,7 @@ extern gimple_seq rewrite_to_defined_overflow (gimple *, bool 
= false);
 extern void replace_call_with_value (gimple_stmt_iterator *, tree);
 extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
 extern void gsi_replace_with_seq_vops (gimple_stmt_iterator *, gimple_seq);
+extern bool can_refer_decl_in_current_unit_p (tree decl, tree from_decl);
 
 /* gimple_build, functionally matching fold_buildN, outputs stmts
    int the provided sequence, matching and simplifying them on-the-fly.
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 2fad2a3d7b6..0dfad0f9bfd 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -396,6 +396,8 @@ ch_base::copy_headers (function *fun)
 
   auto_vec<loop_p> candidates;
   auto_vec<std::pair<edge, loop_p> > copied;
+  auto_vec<class loop *> loops_to_unloop;
+  auto_vec<int> loops_to_unloop_nunroll;
 
   mark_dfs_back_edges ();
   gimple_ranger *ranger = new gimple_ranger;
@@ -408,6 +410,14 @@ ch_base::copy_headers (function *fun)
                 "Analyzing loop %i\n", loop->num);
 
       header = loop->header;
+      if (!get_max_loop_iterations_int (loop))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file, "Loop %d never loops.\n", loop->num);
+         loops_to_unloop.safe_push (loop);
+         loops_to_unloop_nunroll.safe_push (0);
+         continue;
+       }
 
       /* If the loop is already a do-while style one (either because it was
         written as such, or because jump threading transformed it into one),
@@ -593,13 +603,6 @@ ch_base::copy_headers (function *fun)
       /* We possibly decreased number of itrations by 1.  */
       auto_vec<edge> exits = get_loop_exit_edges (loop);
       bool precise = (nexits == (int) exits.length ());
-      if (!get_max_loop_iterations_int (loop))
-       {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "Loop %d no longer loops.\n", loop->num);
-         /* TODO: We can unloop like in tree-ssa-loop-ivcanon.  */
-         precise = false;
-       }
       /* Check that loop may not terminate in other way than via
         basic blocks we duplicated.  */
       if (precise)
@@ -640,7 +643,15 @@ ch_base::copy_headers (function *fun)
                 precise = false;
           }
        }
-      if (precise)
+      if (precise
+         && get_max_loop_iterations_int (loop) == 1)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file, "Loop %d no longer loops.\n", loop->num);
+         loops_to_unloop.safe_push (loop);
+         loops_to_unloop_nunroll.safe_push (0);
+       }
+      else if (precise)
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file,
@@ -688,6 +699,12 @@ ch_base::copy_headers (function *fun)
          BITMAP_FREE (exit_bbs);
        }
     }
+  if (loops_to_unloop.length())
+    {
+      bool irred_invalidated;
+      unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, NULL, 
&irred_invalidated);
+      changed = true;
+    }
   free (bbs);
   free (copied_bbs);
 
diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc
index 9f72d534b7c..ce9712058d4 100644
--- a/gcc/tree-ssa-loop-ivcanon.cc
+++ b/gcc/tree-ssa-loop-ivcanon.cc
@@ -618,8 +618,10 @@ static bitmap peeled_loops;
    LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
    when we need to go into loop closed SSA form.  */
 
-static void
-unloop_loops (bitmap loop_closed_ssa_invalidated,
+void
+unloop_loops (vec<class loop *> &loops_to_unloop,
+             vec<int> &loops_to_unloop_nunroll,
+             bitmap loop_closed_ssa_invalidated,
              bool *irred_invalidated)
 {
   while (loops_to_unloop.length ())
@@ -653,8 +655,6 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
       gsi = gsi_start_bb (latch_edge->dest);
       gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
     }
-  loops_to_unloop.release ();
-  loops_to_unloop_nunroll.release ();
 
   /* Remove edges in peeled copies.  Given remove_path removes dominated
      regions we need to cope with removal of already removed paths.  */
@@ -1326,7 +1326,10 @@ canonicalize_induction_variables (void)
     }
   gcc_assert (!need_ssa_update_p (cfun));
 
-  unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
+  unloop_loops (loops_to_unloop, loops_to_unloop_nunroll,
+               loop_closed_ssa_invalidated, &irred_invalidated);
+  loops_to_unloop.release ();
+  loops_to_unloop_nunroll.release ();
   if (irred_invalidated
       && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
     mark_irreducible_loops ();
@@ -1473,7 +1476,12 @@ tree_unroll_loops_completely (bool may_increase_size, 
bool unroll_outer)
        {
          unsigned i;
 
-          unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
+         unloop_loops (loops_to_unloop,
+                       loops_to_unloop_nunroll,
+                       loop_closed_ssa_invalidated,
+                       &irred_invalidated);
+         loops_to_unloop.release ();
+         loops_to_unloop_nunroll.release ();
 
          /* We cannot use TODO_update_ssa_no_phi because VOPS gets confused.  
*/
          if (loop_closed_ssa_invalidated

Reply via email to