> Hi, > > gcc/ChangeLog: > > > > PR tree-optimization/117790 > > * cfgloopmanip.cc (can_flow_scale_loop_freqs_p): New. > > (flow_scale_loop_freqs): New. > > (scale_loop_freqs_with_exit_counts): New. > > (scale_loop_freqs_hold_exit_counts): New. > > (scale_loop_profile): Refactor to use the newly-added > > scale_loop_profile_1, and use scale_loop_freqs_hold_exit_counts to > > correctly handle reducing the expected niters for loops with multiple > > exits. > > (scale_loop_freqs_with_new_exit_count): New. > > (scale_loop_profile_1): New. > > (scale_loop_profile_hold_exit_counts): New. > > * cfgloopmanip.h (scale_loop_profile_hold_exit_counts): New. > > (scale_loop_freqs_with_new_exit_count): New. > +template<typename ExitCountFn> > +static bool > +can_flow_scale_loop_freqs_p (class loop *loop, > + ExitCountFn get_exit_count) > +{ > + basic_block bb = loop->header; > + > + const profile_count count_in = loop_count_in (loop); > + profile_count exit_count = profile_count::zero (); > + > + while (bb != loop->latch) > + { > + /* Punt if any of the BB counts are uninitialized. */ > + if (!bb->count.initialized_p ()) > + return false; > + > + bool found_exit = false; > + edge internal_edge = nullptr; > + for (auto e : bb->succs) > + if (flow_bb_inside_loop_p (loop, e->dest)) > + { > + if (internal_edge) > + return false; > + internal_edge = e; > > This assumes that there are at most 2 edges out which is not always the > case (i.e. for EH and switch). I suppose vectorizer never calls it > there but probably you want to test that there are precisely two edges > in can_flow_scale_loop_freqs and if not drop message to dump file, so in > case we encounter such loops we notice.
Also forgot to write. Ohter interesting case is when loop has inner loop. In this case there will be 2 edges but both of them internal. It is also possible that the exit of loop sits inside inner loop. Honza