predict.def (PRED_CALL, [...]): New.
* predict.def (PRED_CALL, PRED_ERROR_RETURN): New. * predict.c (estimate_probability): Calculate dominance information; improve detection of NORETURN heuristics; add call/error_return heuiristics; tweak comparison heuristics to recognize -1. From-SVN: r43130
This commit is contained in:
parent
680cd9ed7b
commit
0b92ff33b8
|
@ -1,3 +1,11 @@
|
||||||
|
Sun Jun 10 10:00:17 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* predict.def (PRED_CALL, PRED_ERROR_RETURN): New.
|
||||||
|
* predict.c (estimate_probability): Calculate dominance
|
||||||
|
information; improve detection of NORETURN heuristics;
|
||||||
|
add call/error_return heuiristics; tweak comparison heuristics
|
||||||
|
to recognize -1.
|
||||||
|
|
||||||
2001-06-09 Alexandre Oliva <aoliva@redhat.com>
|
2001-06-09 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
* doc/invoke.texi (C Dialect Options): Document -aux-info.
|
* doc/invoke.texi (C Dialect Options): Document -aux-info.
|
||||||
|
|
|
@ -240,8 +240,14 @@ void
|
||||||
estimate_probability (loops_info)
|
estimate_probability (loops_info)
|
||||||
struct loops *loops_info;
|
struct loops *loops_info;
|
||||||
{
|
{
|
||||||
|
sbitmap *dominators, *post_dominators;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
|
||||||
|
post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
|
||||||
|
calculate_dominance_info (NULL, dominators, 0);
|
||||||
|
calculate_dominance_info (NULL, post_dominators, 1);
|
||||||
|
|
||||||
/* Try to predict out blocks in a loop that are not part of a
|
/* Try to predict out blocks in a loop that are not part of a
|
||||||
natural loop. */
|
natural loop. */
|
||||||
for (i = 0; i < loops_info->num; i++)
|
for (i = 0; i < loops_info->num; i++)
|
||||||
|
@ -282,10 +288,27 @@ estimate_probability (loops_info)
|
||||||
is used as the prediction for the branch. */
|
is used as the prediction for the branch. */
|
||||||
for (i = 0; i < n_basic_blocks - 1; i++)
|
for (i = 0; i < n_basic_blocks - 1; i++)
|
||||||
{
|
{
|
||||||
rtx last_insn = BLOCK_END (i);
|
basic_block bb = BASIC_BLOCK (i);
|
||||||
|
rtx last_insn = bb->end;
|
||||||
rtx cond, earliest;
|
rtx cond, earliest;
|
||||||
edge e;
|
edge e;
|
||||||
|
|
||||||
|
/* If block has no sucessor, predict all possible paths to
|
||||||
|
it as improbable, as the block contains a call to a noreturn
|
||||||
|
function and thus can be executed only once. */
|
||||||
|
if (bb->succ == NULL)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < n_basic_blocks; y++)
|
||||||
|
if (!TEST_BIT (post_dominators[y], i))
|
||||||
|
{
|
||||||
|
for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next)
|
||||||
|
if (e->dest->index >= 0
|
||||||
|
&& TEST_BIT (post_dominators[e->dest->index], i))
|
||||||
|
predict_edge_def (e, PRED_NORETURN, NOT_TAKEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GET_CODE (last_insn) != JUMP_INSN
|
if (GET_CODE (last_insn) != JUMP_INSN
|
||||||
|| ! any_condjump_p (last_insn))
|
|| ! any_condjump_p (last_insn))
|
||||||
continue;
|
continue;
|
||||||
|
@ -293,12 +316,39 @@ estimate_probability (loops_info)
|
||||||
if (find_reg_note (last_insn, REG_BR_PROB, 0))
|
if (find_reg_note (last_insn, REG_BR_PROB, 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If one of the successor blocks has no successors, predict
|
for (e = bb->succ; e; e = e->succ_next)
|
||||||
that side not taken. */
|
{
|
||||||
/* ??? Ought to do the same for any subgraph with no exit. */
|
/* Predict edges to blocks that return immediately to be
|
||||||
for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
|
improbable. These are usually used to signal error states. */
|
||||||
if (e->dest->succ == NULL)
|
if (e->dest == EXIT_BLOCK_PTR
|
||||||
predict_edge_def (e, PRED_NORETURN, NOT_TAKEN);
|
|| (e->dest->succ && !e->dest->succ->succ_next
|
||||||
|
&& e->dest->succ->dest == EXIT_BLOCK_PTR))
|
||||||
|
predict_edge_def (e, PRED_ERROR_RETURN, NOT_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
|
||||||
|
&& TEST_BIT (dominators[e->dest->index], e->src->index)
|
||||||
|
&& !TEST_BIT (post_dominators[e->src->index], e->dest->index))
|
||||||
|
{
|
||||||
|
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 = e->dest->head; insn != NEXT_INSN (e->dest->end);
|
||||||
|
insn = NEXT_INSN (insn))
|
||||||
|
if (GET_CODE (insn) == CALL_INSN
|
||||||
|
/* Constant and pure calls are hardly used to signalize
|
||||||
|
something exceptional. */
|
||||||
|
&& ! CONST_CALL_P (insn))
|
||||||
|
{
|
||||||
|
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cond = get_condition (last_insn, &earliest);
|
cond = get_condition (last_insn, &earliest);
|
||||||
if (! cond)
|
if (! cond)
|
||||||
|
@ -359,7 +409,9 @@ estimate_probability (loops_info)
|
||||||
break;
|
break;
|
||||||
case LE:
|
case LE:
|
||||||
case LT:
|
case LT:
|
||||||
if (XEXP (cond, 1) == const0_rtx)
|
if (XEXP (cond, 1) == const0_rtx
|
||||||
|
|| (GET_CODE (XEXP (cond, 1)) == CONST_INT
|
||||||
|
&& INTVAL (XEXP (cond, 1)) == -1))
|
||||||
predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
|
predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
|
||||||
break;
|
break;
|
||||||
case GE:
|
case GE:
|
||||||
|
@ -385,6 +437,8 @@ estimate_probability (loops_info)
|
||||||
continue;
|
continue;
|
||||||
combine_predictions_for_insn (last_insn, BASIC_BLOCK (i));
|
combine_predictions_for_insn (last_insn, BASIC_BLOCK (i));
|
||||||
}
|
}
|
||||||
|
sbitmap_vector_free (post_dominators);
|
||||||
|
sbitmap_vector_free (dominators);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* __builtin_expect dropped tokens into the insn stream describing
|
/* __builtin_expect dropped tokens into the insn stream describing
|
||||||
|
|
|
@ -44,4 +44,6 @@ DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", PROB_VERY_LIKELY)
|
||||||
DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", PROB_LIKELY)
|
DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", PROB_LIKELY)
|
||||||
DEF_PREDICTOR (PRED_LOOP_HEADER, "loop header", PROB_LIKELY)
|
DEF_PREDICTOR (PRED_LOOP_HEADER, "loop header", PROB_LIKELY)
|
||||||
DEF_PREDICTOR (PRED_POINTER, "pointer", PROB_LIKELY)
|
DEF_PREDICTOR (PRED_POINTER, "pointer", PROB_LIKELY)
|
||||||
|
DEF_PREDICTOR (PRED_CALL, "call", PROB_LIKELY)
|
||||||
|
DEF_PREDICTOR (PRED_ERROR_RETURN, "error return", PROB_LIKELY)
|
||||||
DEF_PREDICTOR (PRED_OPCODE, "opcode", PROB_LIKELY)
|
DEF_PREDICTOR (PRED_OPCODE, "opcode", PROB_LIKELY)
|
||||||
|
|
Loading…
Reference in New Issue