summaryrefslogtreecommitdiff
path: root/gcc/profile.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-28 21:37:35 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-28 21:37:35 +0000
commiteb42964415d14caa18dcc2eca05f04af547fd58f (patch)
tree9dcbd6f10eb7084accad68aa621c0f3eb6a081d1 /gcc/profile.c
parent0dbe40e076463c44e7d824f2eb3a2c63c9e32ab8 (diff)
downloadgcc-eb42964415d14caa18dcc2eca05f04af547fd58f.tar.gz
* basic-block.h (EDGE_FREQUENCY): New macro.
* bb-reorder (fixup_reorder_chain): Set counts and frequencies for new BB/edges. * flow.c (find_sub_basic_blocks): Likewise. (try_crossjump_to_edge): Likewise; use EDGE_FREQUENCY (redirect_edge_and_branch): Use EDGE_FREQUENCY. * predict.c (DEF_PREDICTOR): New argument FLAGS. (HITRATE): New macro. (PRED_FLAG_FIRST_MATCH): New constant. (predictor_info): New field flgags. (combine_predictions_for_insn): Use DS theory to combine probabilities; set the edge probabilities when finished. (estimate_probability): Avoid duplicated matches of LOOP_BRANCH heuristics for nested loops; update comment. * predict.def: Add flags for each prediction, set probabilities according to B&L paper. * predict.h (DEF_PREDICTOR): New argument FLAGS. * profile.c (compute_branch_probabilities): Cleanup way the edge probabilities are computed and REG_BR_PROB notes are dropped; if values does not match, emit error. (init_branch_prob): Do error instead of warning when profile driven feedback is missing or corrupt. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44439 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/profile.c')
-rw-r--r--gcc/profile.c112
1 files changed, 45 insertions, 67 deletions
diff --git a/gcc/profile.c b/gcc/profile.c
index fd03d4be074..ddb621a6d19 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -216,7 +216,6 @@ compute_branch_probabilities ()
int hist_br_prob[20];
int num_never_executed;
int num_branches;
- int bad_counts = 0;
struct bb_info *bb_infos;
/* Attach extra info block to each bb. */
@@ -418,84 +417,63 @@ compute_branch_probabilities ()
{
basic_block bb = BASIC_BLOCK (i);
edge e;
- rtx insn;
gcov_type total;
rtx note;
total = bb->count;
- if (!total)
- continue;
- for (e = bb->succ; e; e = e->succ_next)
- {
- if (any_condjump_p (e->src->end)
- && !EDGE_INFO (e)->ignore
- && !(e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE)))
- {
- int prob;
- /* This calculates the branch probability as an integer between
- 0 and REG_BR_PROB_BASE, properly rounded to the nearest
- integer. Perform the arithmetic in double to avoid
- overflowing the range of ints. */
- if (total == 0)
- prob = -1;
- else
- {
- prob = (((double)e->count * REG_BR_PROB_BASE)
- + (total >> 1)) / total;
- if (prob < 0 || prob > REG_BR_PROB_BASE)
- {
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "bad count: prob for %d-%d thought to be %d (forcibly normalized)\n",
- e->src->index, e->dest->index, prob);
-
- bad_counts = 1;
- prob = REG_BR_PROB_BASE / 2;
- }
-
- /* Match up probability with JUMP pattern. */
- if (e->flags & EDGE_FALLTHRU)
- prob = REG_BR_PROB_BASE - prob;
- }
-
- if (prob == -1)
- num_never_executed++;
- else
+ if (total)
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
+ if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
{
- int index = prob * 20 / REG_BR_PROB_BASE;
- if (index == 20)
- index = 19;
- hist_br_prob[index]++;
+ error ("Corrupted profile info: prob for %d-%d thought to be %d\n",
+ e->src->index, e->dest->index, e->probability);
+ e->probability = REG_BR_PROB_BASE / 2;
}
- num_branches++;
-
- note = find_reg_note (e->src->end, REG_BR_PROB, 0);
+ }
+ if (any_condjump_p (bb->end)
+ && bb->succ->succ_next)
+ {
+ int prob;
+ edge e;
+
+ if (total == 0)
+ prob = -1;
+ else
+ if (total == -1)
+ num_never_executed++;
+ else
+ {
+ int index;
+
+ /* Find the branch edge. It is possible that we do have fake
+ edges here. */
+ for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
+ e = e->succ_next)
+ continue; /* Loop body has been intentionally left blank. */
+
+ prob = e->probability;
+ index = prob * 20 / REG_BR_PROB_BASE;
+
+ if (index == 20)
+ index = 19;
+ hist_br_prob[index]++;
+
+ note = find_reg_note (bb->end, REG_BR_PROB, 0);
/* There may be already note put by some other pass, such
- as builtin_expect expander. */
+ as builtin_expect expander. */
if (note)
XEXP (note, 0) = GEN_INT (prob);
else
- REG_NOTES (e->src->end)
+ REG_NOTES (bb->end)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (e->src->end));
+ REG_NOTES (bb->end));
}
+ num_branches++;
+
}
-
- /* Add a REG_EXEC_COUNT note to the first instruction of this block. */
- insn = next_nonnote_insn (bb->head);
-
- if (GET_CODE (bb->head) == CODE_LABEL)
- insn = next_nonnote_insn (insn);
-
- /* Avoid crash on empty basic blocks. */
- if (insn && INSN_P (insn))
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EXEC_COUNT, GEN_INT (total),
- REG_NOTES (insn));
}
-
- /* This should never happen. */
- if (bad_counts)
- warning ("Arc profiling: some edge counts were bad.");
if (rtl_dump_file)
{
@@ -1004,10 +982,10 @@ end_branch_prob ()
flag will not be set until an attempt is made to read
past the end of the file. */
if (feof (da_file))
- warning (".da file contents exhausted too early\n");
+ error (".da file contents exhausted too early");
/* Should be at end of file now. */
if (__read_long (&temp, da_file, 8) == 0)
- warning (".da file contents not exhausted\n");
+ error (".da file contents not exhausted");
fclose (da_file);
}
}