diff mbox series

Fix loop-ch

Message ID ZEKRXFttQMehkW19@kam.mff.cuni.cz
State New
Headers show
Series Fix loop-ch | expand

Commit Message

Jan Hubicka April 21, 2023, 1:36 p.m. UTC
Hi,
Ondrej Kubanek implemented profiling of loop histograms which sould be useful to improve
i.e. quality of loop peeling of verctorization.  However it turns out that most of histograms
are lost on the way from profiling to loop peeling pass (about 90%).  One common case is the
following latent bug in loop header copying which forgets to update the loop header pointer.

Curiously enough it does work to make single latch and preheader edge by splitting basic blocks
but it works with wrong edge.  As a consequence every loop where loop header was copied is
removed from loop tree and inserted again losing all metadata included.

Patch correctly updates the loop structure and also add verification
that the loop tree is OK after all transforms which is failing without
the patch.

Bootstrapped/regtested x86_64-linux, plan to insteall this as obvious.

Comments

Jan Hubicka April 21, 2023, 3:40 p.m. UTC | #1
> Hi,
> Ondrej Kubanek implemented profiling of loop histograms which sould be useful to improve
> i.e. quality of loop peeling of verctorization.  However it turns out that most of histograms
> are lost on the way from profiling to loop peeling pass (about 90%).  One common case is the
> following latent bug in loop header copying which forgets to update the loop header pointer.
> 
> Curiously enough it does work to make single latch and preheader edge by splitting basic blocks
> but it works with wrong edge.  As a consequence every loop where loop header was copied is
> removed from loop tree and inserted again losing all metadata included.
> 
> Patch correctly updates the loop structure and also add verification
> that the loop tree is OK after all transforms which is failing without
> the patch.
> 
> Bootstrapped/regtested x86_64-linux, plan to insteall this as obvious.
> 
Hi,
sadly I managed to mix up patch and its WIP version in previous commit.
This patch adds the missing edge iterator and also fixes a side case
where new loop header would have multiple latches.

Bootstrapping/regtesting of x86_64-linux in progress.  It was tested
previously and passed, so I hope it will again and commit it to unbreak
master then.

gcc/ChangeLog:

	* tree-ssa-loop-ch.cc (ch_base::copy_headers): Fix previous
	commit.

diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 560df39893e..9487e7f3e55 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -484,7 +484,10 @@ ch_base::copy_headers (function *fun)
       /* Ensure that the header will have just the latch as a predecessor
 	 inside the loop.  */
       if (!single_pred_p (exit->dest))
-	exit = single_pred_edge (split_edge (exit));
+	{
+	  header = split_edge (exit);
+	  exit = single_pred_edge (header);
+	}
 
       entry = loop_preheader_edge (loop);
 
@@ -547,16 +550,17 @@ ch_base::copy_headers (function *fun)
       /* Find correct latch.  We only duplicate chain of conditionals so
 	 there should be precisely two edges to the new header.  One entry
 	 edge and one to latch.  */
+      edge_iterator ei;
+      edge e;
       FOR_EACH_EDGE (e, ei, loop->header->preds)
 	if (header != e->src)
 	  {
 	    loop->latch = e->src;
 	    break;
 	  }
-      /* Ensure that the latch and the preheader is simple (we know that they
-	 are not now, since there was the loop exit condition.  */
-      split_edge (loop_preheader_edge (loop));
-      split_edge (loop_latch_edge (loop));
+      /* Ensure that the latch is simple.  */
+      if (!single_succ_p (loop_latch_edge (loop)->src))
+	split_edge (loop_latch_edge (loop));
 
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
diff mbox series

Patch

diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 6b332719411..2c56b3b3c31 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -557,6 +557,17 @@  ch_base::copy_headers (function *fun)
 	    }
 	}
 
+      /* Update header of the loop.  */
+      loop->header = header;
+      /* Find correct latch.  We only duplicate chain of conditionals so
+         there should be precisely two edges to the new header.  One entry
+         edge and one to latch.  */
+      FOR_EACH_EDGE (e, ei, loop->header->preds)
+	if (header != e->src)
+	  {
+	    loop->latch = e->src;
+	    break;
+	  }
       /* Ensure that the latch and the preheader is simple (we know that they
 	 are not now, since there was the loop exit condition.  */
       split_edge (loop_preheader_edge (loop));
@@ -583,6 +594,8 @@  ch_base::copy_headers (function *fun)
 
   if (changed)
     {
+      if (flag_checking)
+	verify_loop_structure ();
       update_ssa (TODO_update_ssa);
       /* After updating SSA form perform CSE on the loop header
 	 copies.  This is esp. required for the pass before