Commit 429d2750 by Jan Hubicka Committed by Jan Hubicka

predict.c (predicted_by_loop_heuristics_p): New function.

	* predict.c (predicted_by_loop_heuristics_p): New function.
	(predict_iv_comparison): Use it.
	(predict_loops): Walk from innermost loops; do not predict edges
	leaving multiple loops multiple times; implement
	PRED_LOOP_ITERATIONS_MAX heuristics.
	* predict.def (PRED_LOOP_ITERATIONS_MAX): New predictor.
	* gcc.dg/predict-9.c: Update template.

From-SVN: r237103
parent 46f1f3c1
2016-06-03 Jan Hubicka <hubicka@ucw.cz> 2016-06-05 Jan Hubicka <hubicka@ucw.cz>
* predict.c (predicted_by_loop_heuristics_p): New function.
(predict_iv_comparison): Use it.
(predict_loops): Walk from innermost loops; do not predict edges
leaving multiple loops multiple times; implement
PRED_LOOP_ITERATIONS_MAX heuristics.
* predict.def (PRED_LOOP_ITERATIONS_MAX): New predictor.
2016-06-05 Jan Hubicka <hubicka@ucw.cz>
* cfg.c (check_bb_profile): Do not report mismatched profiles when * cfg.c (check_bb_profile): Do not report mismatched profiles when
only edges out of BB are EH edges. only edges out of BB are EH edges.
......
...@@ -1215,6 +1215,27 @@ expr_coherent_p (tree t1, tree t2) ...@@ -1215,6 +1215,27 @@ expr_coherent_p (tree t1, tree t2)
return false; return false;
} }
/* Return true if E is predicted by one of loop heuristics. */
static bool
predicted_by_loop_heuristics_p (basic_block bb)
{
struct edge_prediction *i;
edge_prediction **preds = bb_predictions->get (bb);
if (!preds)
return false;
for (i = *preds; i; i = i->ep_next)
if (i->ep_predictor == PRED_LOOP_ITERATIONS_GUESSED
|| i->ep_predictor == PRED_LOOP_ITERATIONS_MAX
|| i->ep_predictor == PRED_LOOP_ITERATIONS
|| i->ep_predictor == PRED_LOOP_EXIT
|| i->ep_predictor == PRED_LOOP_EXTRA_EXIT)
return true;
return false;
}
/* Predict branch probability of BB when BB contains a branch that compares /* Predict branch probability of BB when BB contains a branch that compares
an induction variable in LOOP with LOOP_IV_BASE_VAR to LOOP_BOUND_VAR. The an induction variable in LOOP with LOOP_IV_BASE_VAR to LOOP_BOUND_VAR. The
loop exit is compared using LOOP_BOUND_CODE, with step of LOOP_BOUND_STEP. loop exit is compared using LOOP_BOUND_CODE, with step of LOOP_BOUND_STEP.
...@@ -1243,10 +1264,7 @@ predict_iv_comparison (struct loop *loop, basic_block bb, ...@@ -1243,10 +1264,7 @@ predict_iv_comparison (struct loop *loop, basic_block bb,
edge then_edge; edge then_edge;
edge_iterator ei; edge_iterator ei;
if (predicted_by_p (bb, PRED_LOOP_ITERATIONS_GUESSED) if (predicted_by_loop_heuristics_p (bb))
|| predicted_by_p (bb, PRED_LOOP_ITERATIONS)
|| predicted_by_p (bb, PRED_LOOP_EXIT)
|| predicted_by_p (bb, PRED_LOOP_EXTRA_EXIT))
return; return;
stmt = last_stmt (bb); stmt = last_stmt (bb);
...@@ -1484,6 +1502,7 @@ predict_extra_loop_exits (edge exit_edge) ...@@ -1484,6 +1502,7 @@ predict_extra_loop_exits (edge exit_edge)
} }
} }
/* Predict edge probabilities by exploiting loop structure. */ /* Predict edge probabilities by exploiting loop structure. */
static void static void
...@@ -1493,10 +1512,10 @@ predict_loops (void) ...@@ -1493,10 +1512,10 @@ predict_loops (void)
/* 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_EACH_LOOP (loop, 0) FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{ {
basic_block bb, *bbs; basic_block bb, *bbs;
unsigned j, n_exits; unsigned j, n_exits = 0;
vec<edge> exits; vec<edge> exits;
struct tree_niter_desc niter_desc; struct tree_niter_desc niter_desc;
edge ex; edge ex;
...@@ -1508,7 +1527,9 @@ predict_loops (void) ...@@ -1508,7 +1527,9 @@ predict_loops (void)
gcond *stmt = NULL; gcond *stmt = NULL;
exits = get_loop_exit_edges (loop); exits = get_loop_exit_edges (loop);
n_exits = exits.length (); FOR_EACH_VEC_ELT (exits, j, ex)
if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE)))
n_exits ++;
if (!n_exits) if (!n_exits)
{ {
exits.release (); exits.release ();
...@@ -1522,7 +1543,14 @@ predict_loops (void) ...@@ -1522,7 +1543,14 @@ predict_loops (void)
int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS); int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
int probability; int probability;
enum br_predictor predictor; enum br_predictor predictor;
widest_int nit;
if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE))
continue;
/* Loop heuristics do not expect exit conditional to be inside
inner loop. We predict from innermost to outermost loop. */
if (predicted_by_loop_heuristics_p (ex->src))
continue;
predict_extra_loop_exits (ex); predict_extra_loop_exits (ex);
if (number_of_iterations_exit (loop, ex, &niter_desc, false, false)) if (number_of_iterations_exit (loop, ex, &niter_desc, false, false))
...@@ -1543,25 +1571,34 @@ predict_loops (void) ...@@ -1543,25 +1571,34 @@ predict_loops (void)
/* If we have just one exit and we can derive some information about /* If we have just one exit and we can derive some information about
the number of iterations of the loop from the statements inside the number of iterations of the loop from the statements inside
the loop, use it to predict this exit. */ the loop, use it to predict this exit. */
else if (n_exits == 1) else if (n_exits == 1
&& estimated_stmt_executions (loop, &nit))
{ {
nitercst = estimated_stmt_executions_int (loop); if (wi::gtu_p (nit, max))
if (nitercst < 0)
continue;
if (nitercst > max)
nitercst = max; nitercst = max;
else
nitercst = nit.to_shwi ();
predictor = PRED_LOOP_ITERATIONS_GUESSED; predictor = PRED_LOOP_ITERATIONS_GUESSED;
} }
/* If we have likely upper bound, trust it for very small iteration
counts. Such loops would otherwise get mispredicted by standard
LOOP_EXIT heuristics. */
else if (n_exits == 1
&& likely_max_stmt_executions (loop, &nit)
&& wi::ltu_p (nit,
RDIV (REG_BR_PROB_BASE,
REG_BR_PROB_BASE
- predictor_info
[PRED_LOOP_EXIT].hitrate)))
{
nitercst = nit.to_shwi ();
predictor = PRED_LOOP_ITERATIONS_MAX;
}
else else
continue; continue;
/* If the prediction for number of iterations is zero, do not gcc_checking_assert (nitercst);
predict the exit edges. */ probability = RDIV (REG_BR_PROB_BASE, nitercst);
if (nitercst == 0)
continue;
probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
predict_edge (ex, predictor, probability); predict_edge (ex, predictor, probability);
} }
exits.release (); exits.release ();
...@@ -1619,8 +1656,7 @@ predict_loops (void) ...@@ -1619,8 +1656,7 @@ predict_loops (void)
if (!header_found if (!header_found
/* If we already used more reliable loop exit predictors, do not /* If we already used more reliable loop exit predictors, do not
bother with PRED_LOOP_EXIT. */ bother with PRED_LOOP_EXIT. */
&& !predicted_by_p (bb, PRED_LOOP_ITERATIONS_GUESSED) && !predicted_by_loop_heuristics_p (bb))
&& !predicted_by_p (bb, PRED_LOOP_ITERATIONS))
{ {
/* For loop with many exits we don't want to predict all exits /* For loop with many exits we don't want to predict all exits
with the pretty large probability, because if all exits are with the pretty large probability, because if all exits are
......
...@@ -73,6 +73,10 @@ DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY, ...@@ -73,6 +73,10 @@ DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY,
DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations", DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations",
PROB_ALWAYS, PRED_FLAG_FIRST_MATCH) PROB_ALWAYS, PRED_FLAG_FIRST_MATCH)
/* Use number of loop iterations guessed by the contents of the loop. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS_MAX, "guessed loop iterations",
PROB_ALWAYS, PRED_FLAG_FIRST_MATCH)
/* Branch containing goto is probably not taken. */ /* Branch containing goto is probably not taken. */
DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (50), 0) DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (50), 0)
......
2016-06-05 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/predict-9.c: Update template.
2016-06-05 Paolo Carlini <paolo.carlini@oracle.com> 2016-06-05 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/49377 PR c++/49377
......
...@@ -19,5 +19,5 @@ void foo (int base) ...@@ -19,5 +19,5 @@ void foo (int base)
} }
} }
/* { dg-final { scan-tree-dump-times "first match heuristics: 2.0%" 4 "profile_estimate"} } */ /* { dg-final { scan-tree-dump-times "first match heuristics: 2.0%" 3 "profile_estimate"} } */
/* { dg-final { scan-tree-dump-times "first match heuristics: 4.5%" 0 "profile_estimate"} } */ /* { dg-final { scan-tree-dump-times "first match heuristics: 4.5%" 1 "profile_estimate"} } */
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