int nedges = 0;
edge e, first = NULL, second = NULL;
edge_iterator ei;
+ int nzero = 0;
+ int nunknown = 0;
FOR_EACH_EDGE (e, ei, bb->succs)
- if (!unlikely_executed_edge_p (e))
- {
- nedges ++;
- if (first && !second)
- second = e;
- if (!first)
- first = e;
- }
- else if (!e->probability.initialized_p ())
- e->probability = profile_probability::never ();
+ {
+ if (!unlikely_executed_edge_p (e))
+ {
+ nedges ++;
+ if (first && !second)
+ second = e;
+ if (!first)
+ first = e;
+ }
+ else if (!e->probability.initialized_p ())
+ e->probability = profile_probability::never ();
+ if (!e->probability.initialized_p ())
+ nunknown++;
+ else if (e->probability == profile_probability::never ())
+ nzero++;
+ }
/* When there is no successor or only one choice, prediction is easy.
}
clear_bb_predictions (bb);
- if ((!bb->count.nonzero_p () || !first->probability.initialized_p ())
- && !dry_run)
+
+ /* If we have only one successor which is unknown, we can compute missing
+ probablity. */
+ if (nunknown == 1)
+ {
+ profile_probability prob = profile_probability::always ();
+ edge missing = NULL;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->probability.initialized_p ())
+ prob -= e->probability;
+ else if (missing == NULL)
+ missing = e;
+ else
+ gcc_unreachable ();
+ missing->probability = prob;
+ }
+ /* If nothing is unknown, we have nothing to update. */
+ else if (!nunknown && nzero != (int)EDGE_COUNT (bb->succs))
+ ;
+ else if (!dry_run)
{
first->probability
= profile_probability::from_reg_br_prob_base (combined_probability);
{
basic_block bb;
- /* We can not compute accurately for large thresholds due to scaled
- frequencies. */
- gcc_assert (threshold <= BB_FREQ_MAX);
-
/* If profile was scaled in a way entry block has count 0, then the function
is deifnitly taking a lot of time. */
if (!ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.nonzero_p ())
return true;
- /* Maximally BB_FREQ_MAX^2 so overflow won't happen. */
profile_count limit = ENTRY_BLOCK_PTR_FOR_FN
(cfun)->count.apply_scale (threshold, 1);
profile_count sum = profile_count::zero ();
gcc_checking_assert (!bb->aux);
}
+ propagate_unlikely_bbs_forward ();
auto_vec<int, 64> nsuccs;
nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun));
FOR_EACH_EDGE (e, ei, bb->preds)
if (!(e->probability == profile_probability::never ()))
{
- e->probability = profile_probability::never ();
if (!(e->src->count == profile_count::zero ()))
{
nsuccs[e->src->index]--;
}
}
}
+ /* Finally all edges from non-0 regions to 0 are unlikely. */
+ FOR_ALL_BB_FN (bb, cfun)
+ if (!(bb->count == profile_count::zero ()))
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->probability == profile_probability::never ())
+ && e->dest->count == profile_count::zero ())
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Edge %i->%i is unlikely because "
+ "it enters unlikely block\n",
+ bb->index, e->dest->index);
+ e->probability = profile_probability::never ();
+ }
}
/* Estimate and propagate basic block frequencies using the given branch