> 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)) {