summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-manip.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-manip.c')
-rw-r--r--gcc/tree-ssa-loop-manip.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 18ed4f62686..5488044b18f 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -1212,7 +1212,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
gimple_stmt_iterator bsi;
use_operand_p op;
bool ok;
- unsigned i, prob, prob_entry, scale_unrolled, scale_rest;
+ 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;
@@ -1224,9 +1225,10 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
/* Let us assume that the unrolled loop is quite likely to be entered. */
if (integer_nonzerop (enter_main_cond))
- prob_entry = REG_BR_PROB_BASE;
+ prob_entry = profile_probability::always ();
else
- prob_entry = PROB_UNROLLED_LOOP_ENTERED * REG_BR_PROB_BASE / 100;
+ prob_entry = profile_probability::guessed_always ()
+ .apply_scale (PROB_UNROLLED_LOOP_ENTERED, 100);
/* The values for scales should keep profile consistent, and somewhat close
to correct.
@@ -1241,11 +1243,11 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
of this change (scale the frequencies of blocks before and after the exit
by appropriate factors). */
scale_unrolled = prob_entry;
- scale_rest = REG_BR_PROB_BASE;
- new_loop = loop_version (loop, enter_main_cond, NULL,
- prob_entry, REG_BR_PROB_BASE - prob_entry,
- scale_unrolled, scale_rest, true);
+ new_loop = loop_version (loop, enter_main_cond, NULL, prob_entry,
+ prob_entry.invert (), scale_unrolled,
+ profile_probability::guessed_always (),
+ true);
gcc_assert (new_loop != NULL);
update_ssa (TODO_update_ssa);
@@ -1259,9 +1261,13 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
/* Since the exit edge will be removed, the frequency of all the blocks
in the loop that are dominated by it must be scaled by
1 / (1 - exit->probability). */
- scale_dominated_blocks_in_loop (loop, exit->src,
- REG_BR_PROB_BASE,
- REG_BR_PROB_BASE - exit->probability);
+ if (exit->probability.initialized_p ())
+ scale_dominated_blocks_in_loop (loop, exit->src,
+ /* We are scaling up here so probability
+ does not fit. */
+ REG_BR_PROB_BASE,
+ REG_BR_PROB_BASE
+ - exit->probability.to_reg_br_prob_base ());
bsi = gsi_last_bb (exit_bb);
exit_if = gimple_build_cond (EQ_EXPR, integer_zero_node,
@@ -1278,11 +1284,11 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
new_exit->count = exit->count;
new_exit->probability = exit->probability;
new_nonexit = single_pred_edge (loop->latch);
- new_nonexit->probability = REG_BR_PROB_BASE - exit->probability;
+ new_nonexit->probability = exit->probability.invert ();
new_nonexit->flags = EDGE_TRUE_VALUE;
new_nonexit->count -= exit->count;
- scale_bbs_frequencies_int (&loop->latch, 1, new_nonexit->probability,
- REG_BR_PROB_BASE);
+ if (new_nonexit->probability.initialized_p ())
+ scale_bbs_frequencies (&loop->latch, 1, new_nonexit->probability);
old_entry = loop_preheader_edge (loop);
new_entry = loop_preheader_edge (new_loop);
@@ -1362,31 +1368,29 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
}
if (freq_h > 0)
{
- gcov_type scale;
/* Avoid dropping loop body profile counter to 0 because of zero count
in loop's preheader. */
if (freq_e == profile_count::zero ())
freq_e = profile_count::from_gcov_type (1);
- /* This should not overflow. */
- scale = freq_e.probability_in (freq_h);
- scale_loop_frequencies (loop, scale, REG_BR_PROB_BASE);
+ 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->count = loop_preheader_edge (loop)->count;
- new_exit->probability = REG_BR_PROB_BASE / (new_est_niter + 1);
+ new_exit->probability = profile_probability::always ()
+ .apply_scale (1, new_est_niter + 1);
rest->count += new_exit->count;
rest->frequency += EDGE_FREQUENCY (new_exit);
new_nonexit = single_pred_edge (loop->latch);
prob = new_nonexit->probability;
- new_nonexit->probability = REG_BR_PROB_BASE - new_exit->probability;
+ new_nonexit->probability = new_exit->probability.invert ();
new_nonexit->count = exit_bb->count - new_exit->count;
- if (prob > 0)
- scale_bbs_frequencies_int (&loop->latch, 1, new_nonexit->probability,
- prob);
+ prob = new_nonexit->probability / prob;
+ if (prob.initialized_p ())
+ scale_bbs_frequencies (&loop->latch, 1, prob);
/* Finally create the new counter for number of iterations and add the new
exit instruction. */