From 0b92ff33b86d469cb4fcfaa645e0d39a7a266de6 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 10 Jun 2001 10:01:57 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++ gcc/predict.c | 70 +++++++++++++++++++++++++++++++++++++++++++------ gcc/predict.def | 2 ++ 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca22a3112d0..954d6a5abe9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Sun Jun 10 10:00:17 CEST 2001 Jan Hubicka + + * 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 * doc/invoke.texi (C Dialect Options): Document -aux-info. diff --git a/gcc/predict.c b/gcc/predict.c index d4210e030cb..21c7149070f 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -240,8 +240,14 @@ void estimate_probability (loops_info) struct loops *loops_info; { + sbitmap *dominators, *post_dominators; 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 natural loop. */ for (i = 0; i < loops_info->num; i++) @@ -282,10 +288,27 @@ estimate_probability (loops_info) is used as the prediction for the branch. */ 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; 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 || ! any_condjump_p (last_insn)) continue; @@ -293,12 +316,39 @@ estimate_probability (loops_info) if (find_reg_note (last_insn, REG_BR_PROB, 0)) continue; - /* If one of the successor blocks has no successors, predict - that side not taken. */ - /* ??? Ought to do the same for any subgraph with no exit. */ - for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next) - if (e->dest->succ == NULL) - predict_edge_def (e, PRED_NORETURN, NOT_TAKEN); + for (e = bb->succ; e; e = e->succ_next) + { + /* Predict edges to blocks that return immediately to be + improbable. These are usually used to signal error states. */ + if (e->dest == EXIT_BLOCK_PTR + || (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); if (! cond) @@ -359,7 +409,9 @@ estimate_probability (loops_info) break; case LE: 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); break; case GE: @@ -385,6 +437,8 @@ estimate_probability (loops_info) continue; 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 diff --git a/gcc/predict.def b/gcc/predict.def index ce0fbbdf773..9f000b95ca8 100644 --- a/gcc/predict.def +++ b/gcc/predict.def @@ -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_HEADER, "loop header", 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) -- 2.30.2