@@ -1773,3 +1773,46 @@ loop_version (class loop *loop,
return nloop;
}
+
+/* Recacluate the COUNTs of BBs in LOOP, if the probility of exit edge
+ is NEW_EXIT_P. */
+
+bool
+recompute_loop_frequencies (class loop *loop, profile_probability new_exit_p)
+{
+ edge exit = single_exit (loop);
+ if (!exit)
+ return false;
+
+ basic_block * bbs;
+ profile_count exit_count = loop_preheader_edge (loop)->count ();
+ profile_probability exit_p = exit_count.probability_in (loop->header->count);
+ profile_count base_count = loop->header->count;
+ profile_count after_num = base_count.apply_probability (exit_p);
+ profile_count after_den = base_count.apply_probability (new_exit_p);
+
+ /* Update BB counts in loop body.
+ COUNT<exit> = COUNT<pre-header>
+ COUNT<exit> = COUNT<header> * exit_edge_probility
+ The COUNT<new_header>=COUNT<old_header> * old_exit_p / new_exit_p. */
+ bbs = get_loop_body (loop);
+ scale_bbs_frequencies_profile_count (bbs, loop->num_nodes, after_num,
+ after_den);
+ free (bbs);
+
+ /* Update probability and count of latch. */
+ edge new_nonexit = single_pred_edge (loop->latch);
+ new_nonexit->probability = new_exit_p.invert ();
+ loop->latch->count
+ = loop->header->count.apply_probability (new_nonexit->probability);
+
+ /* Update probability and count of exit destination. */
+ edge e;
+ edge_iterator ei;
+ exit->probability = new_exit_p;
+ exit->dest->count = profile_count::zero ();
+ FOR_EACH_EDGE (e, ei, exit->dest->preds)
+ exit->dest->count += e->src->count.apply_probability (e->probability);
+
+ return true;
+}
@@ -62,5 +62,5 @@ class loop * loop_version (class loop *, void *,
basic_block *,
profile_probability, profile_probability,
profile_probability, profile_probability, bool);
-
+extern bool recompute_loop_frequencies (class loop *, profile_probability);
#endif /* GCC_CFGLOOPMANIP_H */
@@ -1251,7 +1251,6 @@ tree_transform_and_unroll_loop (class loop *loop, unsigned factor,
bool ok;
unsigned i;
profile_probability prob, prob_entry, scale_unrolled;
- profile_count freq_e, freq_h;
gcov_type new_est_niter = niter_for_unrolled_loop (loop, factor);
unsigned irr = loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP;
auto_vec<edge> to_remove;
@@ -1393,33 +1392,12 @@ tree_transform_and_unroll_loop (class loop *loop, unsigned factor,
number of iterations, and change the probability of the new
exit edge. */
- freq_h = loop->header->count;
- freq_e = (loop_preheader_edge (loop))->count ();
- if (freq_h.nonzero_p ())
- {
- /* Avoid dropping loop body profile counter to 0 because of zero count
- in loop's preheader. */
- if (freq_h.nonzero_p () && !(freq_e == profile_count::zero ()))
- freq_e = freq_e.force_nonzero ();
- scale_loop_frequencies (loop, freq_e.probability_in (freq_h));
- }
-
- exit_bb = single_pred (loop->latch);
- new_exit = find_edge (exit_bb, rest);
- new_exit->probability = profile_probability::always ()
- .apply_scale (1, new_est_niter + 1);
-
- rest->count += new_exit->count ();
-
- new_nonexit = single_pred_edge (loop->latch);
- prob = new_nonexit->probability;
- new_nonexit->probability = new_exit->probability.invert ();
- prob = new_nonexit->probability / prob;
- if (prob.initialized_p ())
- scale_bbs_frequencies (&loop->latch, 1, prob);
+ prob = profile_probability::always ().apply_scale (1, new_est_niter + 1);
+ recompute_loop_frequencies (loop, prob);
/* Finally create the new counter for number of iterations and add the new
exit instruction. */
+ exit_bb = single_pred (loop->latch);
bsi = gsi_last_nondebug_bb (exit_bb);
exit_if = as_a <gcond *> (gsi_stmt (bsi));
create_iv (exit_base, exit_step, NULL_TREE, loop,