The following makes irreducible region discovery handle multiple latches. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
2021-06-14 Richard Biener <rguent...@suse.de> * cfgloopanal.c (mark_irreducible_loops): Use a dominance check to identify loop latches. * cfgloop.c (verify_loop_structure): Likewise. * loop-init.c (apply_loop_flags): Allow marked irreducible regions even with multiple latches. * predict.c (rebuild_frequencies): Simplify. --- gcc/cfgloop.c | 14 ++++++++++---- gcc/cfgloopanal.c | 2 +- gcc/loop-init.c | 3 ++- gcc/predict.c | 3 +-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 4e227cd0891..f094538b9ff 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -1555,11 +1555,17 @@ verify_loop_structure (void) error ("loop %d%'s header does not belong directly to it", i); err = 1; } - if (loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) - && (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)) + if (loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) { - error ("loop %d%'s latch is marked as part of irreducible region", i); - err = 1; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, loop->header->preds) + if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header) + && e->flags & EDGE_IRREDUCIBLE_LOOP) + { + error ("loop %d%'s latch is marked as part of irreducible" + " region", i); + err = 1; + } } } diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index d0eade3dd34..54426b54881 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -113,7 +113,7 @@ mark_irreducible_loops (void) /* Ignore latch edges. */ if (e->dest->loop_father->header == e->dest - && e->dest->loop_father->latch == act) + && dominated_by_p (CDI_DOMINATORS, act, e->dest)) continue; /* Edges inside a single loop should be left where they are. Edges diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 17f14075f62..1fde0ede441 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -48,7 +48,8 @@ apply_loop_flags (unsigned flags) not work). However, we avoid modifying cfg, which some passes may want. */ gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES - | LOOPS_HAVE_RECORDED_EXITS)) == 0); + | LOOPS_HAVE_RECORDED_EXITS + | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) == 0); loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES); } else diff --git a/gcc/predict.c b/gcc/predict.c index 5d0cae5c4a4..d751e6cecce 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -4287,8 +4287,7 @@ rebuild_frequencies (void) if (profile_status_for_fn (cfun) == PROFILE_GUESSED) { - loop_optimizer_init (0); - mark_irreducible_loops (); + loop_optimizer_init (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS); connect_infinite_loops_to_exit (); estimate_bb_frequencies (true); remove_fake_exit_edges (); -- 2.26.2