Commit 87022a6b by Jan Hubicka Committed by Jan Hubicka

basic-block.h (guess_outgoing_edge_probabilities): Declare.


	* basic-block.h (guess_outgoing_edge_probabilities): Declare.
	* cfgbuild.c (compute_outgoing_frequencies): When probability is missing,
	guess it.
	(find_many_sub_basic_blocks): Do update profile only when it is present.
	* predict.c (set_even_probabilities): Break out from ...
	(combine_predictions_for_insn): ... here; deal with !can_predict_insn_p insns.
	(combine_predictions_for_bb): Use set_even_probabilities.
	(bb_estimate_probability_locally): Break out from ....
	(estimate_probability): ... here.
	(guess_outgoing_edge_probabilities): New entry point.

From-SVN: r87234
parent 3b5edfee
2004-09-09 Jan Hubicka <jh@suse.cz>
* basic-block.h (guess_outgoing_edge_probabilities): Declare.
* cfgbuild.c (compute_outgoing_frequencies): When probability is missing,
guess it.
(find_many_sub_basic_blocks): Do update profile only when it is present.
* predict.c (set_even_probabilities): Break out from ...
(combine_predictions_for_insn): ... here; deal with !can_predict_insn_p insns.
(combine_predictions_for_bb): Use set_even_probabilities.
(bb_estimate_probability_locally): Break out from ....
(estimate_probability): ... here.
(guess_outgoing_edge_probabilities): New entry point.
2004-09-09 Nathan Sidwell <nathan@codesourcery.com> 2004-09-09 Nathan Sidwell <nathan@codesourcery.com>
* gcc.c (add_sysrooted_prefix, execute, do_self_spec, do_spec_1, * gcc.c (add_sysrooted_prefix, execute, do_self_spec, do_spec_1,
......
...@@ -622,6 +622,7 @@ extern bool rtl_predicted_by_p (basic_block, enum br_predictor); ...@@ -622,6 +622,7 @@ extern bool rtl_predicted_by_p (basic_block, enum br_predictor);
extern void tree_predict_edge (edge, enum br_predictor, int); extern void tree_predict_edge (edge, enum br_predictor, int);
extern void rtl_predict_edge (edge, enum br_predictor, int); extern void rtl_predict_edge (edge, enum br_predictor, int);
extern void predict_edge_def (edge, enum br_predictor, enum prediction); extern void predict_edge_def (edge, enum br_predictor, enum prediction);
extern void guess_outgoing_edge_probabilities (basic_block);
/* In flow.c */ /* In flow.c */
extern void init_flow (void); extern void init_flow (void);
......
...@@ -646,9 +646,8 @@ compute_outgoing_frequencies (basic_block b) ...@@ -646,9 +646,8 @@ compute_outgoing_frequencies (basic_block b)
rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL); rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
int probability; int probability;
if (!note) if (note)
return; {
probability = INTVAL (XEXP (note, 0)); probability = INTVAL (XEXP (note, 0));
e = BRANCH_EDGE (b); e = BRANCH_EDGE (b);
e->probability = probability; e->probability = probability;
...@@ -657,6 +656,8 @@ compute_outgoing_frequencies (basic_block b) ...@@ -657,6 +656,8 @@ compute_outgoing_frequencies (basic_block b)
f = FALLTHRU_EDGE (b); f = FALLTHRU_EDGE (b);
f->probability = REG_BR_PROB_BASE - probability; f->probability = REG_BR_PROB_BASE - probability;
f->count = b->count - e->count; f->count = b->count - e->count;
return;
}
} }
if (b->succ && !b->succ->succ_next) if (b->succ && !b->succ->succ_next)
...@@ -664,7 +665,13 @@ compute_outgoing_frequencies (basic_block b) ...@@ -664,7 +665,13 @@ compute_outgoing_frequencies (basic_block b)
e = b->succ; e = b->succ;
e->probability = REG_BR_PROB_BASE; e->probability = REG_BR_PROB_BASE;
e->count = b->count; e->count = b->count;
return;
} }
guess_outgoing_edge_probabilities (b);
if (b->count)
for (e = b->succ; e; e = e->succ_next)
e->count = ((b->count * e->probability + REG_BR_PROB_BASE / 2)
/ REG_BR_PROB_BASE);
} }
/* Assume that someone emitted code with control flow instructions to the /* Assume that someone emitted code with control flow instructions to the
...@@ -698,6 +705,7 @@ find_many_sub_basic_blocks (sbitmap blocks) ...@@ -698,6 +705,7 @@ find_many_sub_basic_blocks (sbitmap blocks)
/* Update branch probabilities. Expect only (un)conditional jumps /* Update branch probabilities. Expect only (un)conditional jumps
to be created with only the forward edges. */ to be created with only the forward edges. */
if (profile_status != PROFILE_ABSENT)
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb) FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
{ {
edge e; edge e;
......
...@@ -313,14 +313,32 @@ dump_prediction (FILE *file, enum br_predictor predictor, int probability, ...@@ -313,14 +313,32 @@ dump_prediction (FILE *file, enum br_predictor predictor, int probability,
fprintf (file, "\n"); fprintf (file, "\n");
} }
/* We can not predict the probabilities of ougtoing edges of bb. Set them
evenly and hope for the best. */
static void
set_even_probabilities (basic_block bb)
{
int nedges = 0;
edge e;
for (e = bb->succ; e; e = e->succ_next)
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
nedges ++;
for (e = bb->succ; e; e = e->succ_next)
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
e->probability = (REG_BR_PROB_BASE + nedges / 2) / nedges;
else
e->probability = 0;
}
/* Combine all REG_BR_PRED notes into single probability and attach REG_BR_PROB /* Combine all REG_BR_PRED notes into single probability and attach REG_BR_PROB
note if not already present. Remove now useless REG_BR_PRED notes. */ note if not already present. Remove now useless REG_BR_PRED notes. */
static void static void
combine_predictions_for_insn (rtx insn, basic_block bb) combine_predictions_for_insn (rtx insn, basic_block bb)
{ {
rtx prob_note = find_reg_note (insn, REG_BR_PROB, 0); rtx prob_note;
rtx *pnote = &REG_NOTES (insn); rtx *pnote;
rtx note; rtx note;
int best_probability = PROB_EVEN; int best_probability = PROB_EVEN;
int best_predictor = END_PREDICTORS; int best_predictor = END_PREDICTORS;
...@@ -329,6 +347,14 @@ combine_predictions_for_insn (rtx insn, basic_block bb) ...@@ -329,6 +347,14 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
bool first_match = false; bool first_match = false;
bool found = false; bool found = false;
if (!can_predict_insn_p (insn))
{
set_even_probabilities (bb);
return;
}
prob_note = find_reg_note (insn, REG_BR_PROB, 0);
pnote = &REG_NOTES (insn);
if (dump_file) if (dump_file)
fprintf (dump_file, "Predictions for insn %i bb %i\n", INSN_UID (insn), fprintf (dump_file, "Predictions for insn %i bb %i\n", INSN_UID (insn),
bb->index); bb->index);
...@@ -446,11 +472,8 @@ combine_predictions_for_bb (FILE *file, basic_block bb) ...@@ -446,11 +472,8 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
this later. */ this later. */
if (nedges != 2) if (nedges != 2)
{ {
for (e = bb->succ; e; e = e->succ_next) if (!bb->count)
if (!(e->flags & (EDGE_EH | EDGE_FAKE))) set_even_probabilities (bb);
e->probability = (REG_BR_PROB_BASE + nedges / 2) / nedges;
else
e->probability = 0;
bb_ann (bb)->predictions = NULL; bb_ann (bb)->predictions = NULL;
if (file) if (file)
fprintf (file, "%i edges in bb %i predicted to even probabilities\n", fprintf (file, "%i edges in bb %i predicted to even probabilities\n",
...@@ -521,8 +544,11 @@ combine_predictions_for_bb (FILE *file, basic_block bb) ...@@ -521,8 +544,11 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
} }
bb_ann (bb)->predictions = NULL; bb_ann (bb)->predictions = NULL;
if (!bb->count)
{
first->probability = combined_probability; first->probability = combined_probability;
second->probability = REG_BR_PROB_BASE - combined_probability; second->probability = REG_BR_PROB_BASE - combined_probability;
}
} }
/* Predict edge probabilities by exploiting loop structure. /* Predict edge probabilities by exploiting loop structure.
...@@ -615,75 +641,19 @@ predict_loops (struct loops *loops_info, bool simpleloops) ...@@ -615,75 +641,19 @@ predict_loops (struct loops *loops_info, bool simpleloops)
} }
} }
/* Statically estimate the probability that a branch will be taken and produce /* Attempt to predict probabilities of BB outgoing edges using local
estimated profile. When profile feedback is present never executed portions properties. */
of function gets estimated. */ static void
bb_estimate_probability_locally (basic_block bb)
void
estimate_probability (struct loops *loops_info)
{ {
basic_block bb;
connect_infinite_loops_to_exit ();
calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_POST_DOMINATORS);
predict_loops (loops_info, true);
iv_analysis_done ();
/* Attempt to predict conditional jumps using a number of heuristics. */
FOR_EACH_BB (bb)
{
rtx last_insn = BB_END (bb); rtx last_insn = BB_END (bb);
rtx cond; rtx cond;
edge e;
if (! can_predict_insn_p (last_insn)) if (! can_predict_insn_p (last_insn))
continue; return;
for (e = bb->succ; e; e = e->succ_next)
{
/* Predict early returns to be probable, as we've already taken
care for error returns and other are often used for fast paths
trought function. */
if ((e->dest == EXIT_BLOCK_PTR
|| (e->dest->succ && !e->dest->succ->succ_next
&& e->dest->succ->dest == EXIT_BLOCK_PTR))
&& !predicted_by_p (bb, PRED_NULL_RETURN)
&& !predicted_by_p (bb, PRED_CONST_RETURN)
&& !predicted_by_p (bb, PRED_NEGATIVE_RETURN)
&& !last_basic_block_p (e->dest))
predict_edge_def (e, PRED_EARLY_RETURN, TAKEN);
/* Look for block we are guarding (ie we dominate it,
but it doesn't postdominate us). */
if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
&& dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
rtx insn;
/* The call heuristic claims that a guarded function call
is improbable. This is because such calls are often used
to signal exceptional situations such as printing error
messages. */
for (insn = BB_HEAD (e->dest); insn != NEXT_INSN (BB_END (e->dest));
insn = NEXT_INSN (insn))
if (CALL_P (insn)
/* Constant and pure calls are hardly used to signalize
something exceptional. */
&& ! CONST_OR_PURE_CALL_P (insn))
{
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
break;
}
}
}
cond = get_condition (last_insn, NULL, false, false); cond = get_condition (last_insn, NULL, false, false);
if (! cond) if (! cond)
continue; return;
/* Try "pointer heuristic." /* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false. A comparison ptr == 0 is predicted as false.
...@@ -768,6 +738,73 @@ estimate_probability (struct loops *loops_info) ...@@ -768,6 +738,73 @@ estimate_probability (struct loops *loops_info)
default: default:
break; break;
} }
}
/* Statically estimate the probability that a branch will be taken and produce
estimated profile. When profile feedback is present never executed portions
of function gets estimated. */
void
estimate_probability (struct loops *loops_info)
{
basic_block bb;
connect_infinite_loops_to_exit ();
calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_POST_DOMINATORS);
predict_loops (loops_info, true);
iv_analysis_done ();
/* Attempt to predict conditional jumps using a number of heuristics. */
FOR_EACH_BB (bb)
{
rtx last_insn = BB_END (bb);
edge e;
if (! can_predict_insn_p (last_insn))
continue;
for (e = bb->succ; e; e = e->succ_next)
{
/* Predict early returns to be probable, as we've already taken
care for error returns and other are often used for fast paths
trought function. */
if ((e->dest == EXIT_BLOCK_PTR
|| (e->dest->succ && !e->dest->succ->succ_next
&& e->dest->succ->dest == EXIT_BLOCK_PTR))
&& !predicted_by_p (bb, PRED_NULL_RETURN)
&& !predicted_by_p (bb, PRED_CONST_RETURN)
&& !predicted_by_p (bb, PRED_NEGATIVE_RETURN)
&& !last_basic_block_p (e->dest))
predict_edge_def (e, PRED_EARLY_RETURN, TAKEN);
/* Look for block we are guarding (ie we dominate it,
but it doesn't postdominate us). */
if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
&& dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
rtx insn;
/* The call heuristic claims that a guarded function call
is improbable. This is because such calls are often used
to signal exceptional situations such as printing error
messages. */
for (insn = BB_HEAD (e->dest); insn != NEXT_INSN (BB_END (e->dest));
insn = NEXT_INSN (insn))
if (CALL_P (insn)
/* Constant and pure calls are hardly used to signalize
something exceptional. */
&& ! CONST_OR_PURE_CALL_P (insn))
{
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
break;
}
}
}
bb_estimate_probability_locally (bb);
} }
/* Attach the combined probability to each conditional jump. */ /* Attach the combined probability to each conditional jump. */
...@@ -809,6 +846,14 @@ estimate_probability (struct loops *loops_info) ...@@ -809,6 +846,14 @@ estimate_probability (struct loops *loops_info)
profile_status = PROFILE_GUESSED; profile_status = PROFILE_GUESSED;
} }
/* Set edge->probability for each succestor edge of BB. */
void
guess_outgoing_edge_probabilities (basic_block bb)
{
bb_estimate_probability_locally (bb);
combine_predictions_for_insn (BB_END (bb), bb);
}
/* Predict using opcode of the last statement in basic block. */ /* Predict using opcode of the last statement in basic block. */
static void static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment