aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-06-10 10:01:57 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-06-10 08:01:57 +0000
commit0b92ff33b86d469cb4fcfaa645e0d39a7a266de6 (patch)
tree85be21b7941eb12af078af9b59979abfebe2ecf5
parent680cd9ed7be2e8bef6a37d41b1078ebac782b70e (diff)
downloadgcc-0b92ff33b86d469cb4fcfaa645e0d39a7a266de6.zip
gcc-0b92ff33b86d469cb4fcfaa645e0d39a7a266de6.tar.gz
gcc-0b92ff33b86d469cb4fcfaa645e0d39a7a266de6.tar.bz2
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/predict.c70
-rw-r--r--gcc/predict.def2
3 files changed, 72 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca22a31..954d6a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
* doc/invoke.texi (C Dialect Options): Document -aux-info.
diff --git a/gcc/predict.c b/gcc/predict.c
index d4210e0..21c7149 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 ce0fbbd..9f000b9 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)