Commit 8e88f9fd by Sebastian Pop Committed by Sebastian Pop

Recompute profile after Graphite.

2009-08-05  Sebastian Pop  <sebastian.pop@amd.com>

	* Makefile.in (graphite.o): Depends on PREDICT_H.
	* graphite.c: Include predict.h.
	(graphite_finalize): Call tree_estimate_probability.
	* predict.c (predict_loops): Do not call scev_initialize and
	scev_finalize.
	(tree_estimate_probability_bb): New.
	(tree_estimate_probability): Do not initialize loops: move that
	code to the driver.  Call tree_estimate_probability_bb.
	(tree_estimate_probability_driver): New.
	(pass_profile): Use tree_estimate_probability_driver.
	* predict.h (tree_estimate_probability): Declared.

From-SVN: r150684
parent 87d4d0ee
2009-08-12 Sebastian Pop <sebastian.pop@amd.com> 2009-08-12 Sebastian Pop <sebastian.pop@amd.com>
* Makefile.in (graphite.o): Depends on PREDICT_H.
* graphite.c: Include predict.h.
(graphite_finalize): Call tree_estimate_probability.
* predict.c (predict_loops): Do not call scev_initialize and
scev_finalize.
(tree_estimate_probability_bb): New.
(tree_estimate_probability): Do not initialize loops: move that
code to the driver. Call tree_estimate_probability_bb.
(tree_estimate_probability_driver): New.
(pass_profile): Use tree_estimate_probability_driver.
* predict.h (tree_estimate_probability): Declared.
2009-08-12 Sebastian Pop <sebastian.pop@amd.com>
* graphite-clast-to-gimple.c (gloog): Add time to TV_GRAPHITE_CODE_GEN. * graphite-clast-to-gimple.c (gloog): Add time to TV_GRAPHITE_CODE_GEN.
* graphite-dependences.c (graphite_legal_transform): Add time to * graphite-dependences.c (graphite_legal_transform): Add time to
TV_GRAPHITE_DATA_DEPS. TV_GRAPHITE_DATA_DEPS.
......
2009-08-05 Sebastian Pop <sebastian.pop@amd.com> 2009-08-05 Sebastian Pop <sebastian.pop@amd.com>
* Makefile.in (graphite.o): Depends on PREDICT_H.
* graphite.c: Include predict.h.
(graphite_finalize): Call tree_estimate_probability.
* predict.c (predict_loops): Do not call scev_initialize and
scev_finalize.
(tree_estimate_probability_bb): New.
(tree_estimate_probability): Do not initialize loops: move that
code to the driver. Call tree_estimate_probability_bb.
(tree_estimate_probability_driver): New.
(pass_profile): Use tree_estimate_probability_driver.
* predict.h (tree_estimate_probability): Declared.
2009-08-05 Sebastian Pop <sebastian.pop@amd.com>
* graphite-clast-to-gimple.c (gloog): Add time to TV_GRAPHITE_CODE_GEN. * graphite-clast-to-gimple.c (gloog): Add time to TV_GRAPHITE_CODE_GEN.
* graphite-dependences.c (graphite_legal_transform): Add time to * graphite-dependences.c (graphite_legal_transform): Add time to
TV_GRAPHITE_DATA_DEPS. TV_GRAPHITE_DATA_DEPS.
......
...@@ -2466,7 +2466,7 @@ sese.o: sese.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ ...@@ -2466,7 +2466,7 @@ sese.o: sese.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
graphite.o: graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ graphite.o: graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \
$(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \ $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) \
$(TREE_DATA_REF_H) tree-pass.h graphite.h \ $(PREDICT_H) $(TREE_DATA_REF_H) tree-pass.h graphite.h \
pointer-set.h value-prof.h graphite-ppl.h sese.h \ pointer-set.h value-prof.h graphite-ppl.h sese.h \
graphite-scop-detection.h graphite-clast-to-gimple.h \ graphite-scop-detection.h graphite-clast-to-gimple.h \
graphite-poly.h graphite-sese-to-poly.h graphite-poly.h graphite-sese-to-poly.h
......
...@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h" #include "pointer-set.h"
#include "gimple.h" #include "gimple.h"
#include "sese.h" #include "sese.h"
#include "predict.h"
#ifdef HAVE_cloog #ifdef HAVE_cloog
...@@ -229,7 +230,12 @@ static void ...@@ -229,7 +230,12 @@ static void
graphite_finalize (bool need_cfg_cleanup_p) graphite_finalize (bool need_cfg_cleanup_p)
{ {
if (need_cfg_cleanup_p) if (need_cfg_cleanup_p)
cleanup_tree_cfg (); {
cleanup_tree_cfg ();
profile_status = PROFILE_ABSENT;
release_recorded_exits ();
tree_estimate_probability ();
}
cloog_finalize (); cloog_finalize ();
free_original_copy_tables (); free_original_copy_tables ();
......
...@@ -916,8 +916,6 @@ predict_loops (void) ...@@ -916,8 +916,6 @@ predict_loops (void)
loop_iterator li; loop_iterator li;
struct loop *loop; struct loop *loop;
scev_initialize ();
/* 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 (li, loop, 0) FOR_EACH_LOOP (li, loop, 0)
...@@ -1040,8 +1038,6 @@ predict_loops (void) ...@@ -1040,8 +1038,6 @@ predict_loops (void)
/* Free basic blocks from get_loop_body. */ /* Free basic blocks from get_loop_body. */
free (bbs); free (bbs);
} }
scev_finalize ();
} }
/* Attempt to predict probabilities of BB outgoing edges using local /* Attempt to predict probabilities of BB outgoing edges using local
...@@ -1608,16 +1604,96 @@ assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value, ...@@ -1608,16 +1604,96 @@ assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value,
} }
#endif #endif
/* Predict branch probabilities and estimate profile of the tree CFG. */ /* Predict branch probabilities and estimate profile for basic block BB. */
static unsigned int
static void
tree_estimate_probability_bb (basic_block bb)
{
edge e;
edge_iterator ei;
gimple last;
FOR_EACH_EDGE (e, ei, bb->succs)
{
/* Predict early returns to be probable, as we've already taken
care for error returns and other cases are often used for
fast paths through function.
Since we've already removed the return statements, we are
looking for CFG like:
if (conditional)
{
..
goto return_block
}
some other blocks
return_block:
return_stmt. */
if (e->dest != bb->next_bb
&& e->dest != EXIT_BLOCK_PTR
&& single_succ_p (e->dest)
&& single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
&& (last = last_stmt (e->dest)) != NULL
&& gimple_code (last) == GIMPLE_RETURN)
{
edge e1;
edge_iterator ei1;
if (single_succ_p (bb))
{
FOR_EACH_EDGE (e1, ei1, bb->preds)
if (!predicted_by_p (e1->src, PRED_NULL_RETURN)
&& !predicted_by_p (e1->src, PRED_CONST_RETURN)
&& !predicted_by_p (e1->src, PRED_NEGATIVE_RETURN))
predict_edge_def (e1, PRED_TREE_EARLY_RETURN, NOT_TAKEN);
}
else
if (!predicted_by_p (e->src, PRED_NULL_RETURN)
&& !predicted_by_p (e->src, PRED_CONST_RETURN)
&& !predicted_by_p (e->src, PRED_NEGATIVE_RETURN))
predict_edge_def (e, PRED_TREE_EARLY_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
&& dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
gimple_stmt_iterator bi;
/* 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 (bi = gsi_start_bb (e->dest); !gsi_end_p (bi);
gsi_next (&bi))
{
gimple stmt = gsi_stmt (bi);
if (is_gimple_call (stmt)
/* Constant and pure calls are hardly used to signalize
something exceptional. */
&& gimple_has_side_effects (stmt))
{
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
break;
}
}
}
}
tree_predict_by_opcode (bb);
}
/* Predict branch probabilities and estimate profile of the tree CFG.
This function can be called from the loop optimizers to recompute
the profile information. */
void
tree_estimate_probability (void) tree_estimate_probability (void)
{ {
basic_block bb; basic_block bb;
loop_optimizer_init (0);
if (dump_file && (dump_flags & TDF_DETAILS))
flow_loops_dump (dump_file, NULL, 0);
add_noreturn_fake_exit_edges (); add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit (); connect_infinite_loops_to_exit ();
/* We use loop_niter_by_eval, which requires that the loops have /* We use loop_niter_by_eval, which requires that the loops have
...@@ -1627,89 +1703,14 @@ tree_estimate_probability (void) ...@@ -1627,89 +1703,14 @@ tree_estimate_probability (void)
bb_predictions = pointer_map_create (); bb_predictions = pointer_map_create ();
tree_bb_level_predictions (); tree_bb_level_predictions ();
mark_irreducible_loops ();
record_loop_exits (); record_loop_exits ();
if (number_of_loops () > 1) if (number_of_loops () > 1)
predict_loops (); predict_loops ();
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ tree_estimate_probability_bb (bb);
edge e;
edge_iterator ei;
gimple last;
FOR_EACH_EDGE (e, ei, bb->succs)
{
/* Predict early returns to be probable, as we've already taken
care for error returns and other cases are often used for
fast paths through function.
Since we've already removed the return statements, we are
looking for CFG like:
if (conditional)
{
..
goto return_block
}
some other blocks
return_block:
return_stmt. */
if (e->dest != bb->next_bb
&& e->dest != EXIT_BLOCK_PTR
&& single_succ_p (e->dest)
&& single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
&& (last = last_stmt (e->dest)) != NULL
&& gimple_code (last) == GIMPLE_RETURN)
{
edge e1;
edge_iterator ei1;
if (single_succ_p (bb))
{
FOR_EACH_EDGE (e1, ei1, bb->preds)
if (!predicted_by_p (e1->src, PRED_NULL_RETURN)
&& !predicted_by_p (e1->src, PRED_CONST_RETURN)
&& !predicted_by_p (e1->src, PRED_NEGATIVE_RETURN))
predict_edge_def (e1, PRED_TREE_EARLY_RETURN, NOT_TAKEN);
}
else
if (!predicted_by_p (e->src, PRED_NULL_RETURN)
&& !predicted_by_p (e->src, PRED_CONST_RETURN)
&& !predicted_by_p (e->src, PRED_NEGATIVE_RETURN))
predict_edge_def (e, PRED_TREE_EARLY_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
&& dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
gimple_stmt_iterator bi;
/* 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 (bi = gsi_start_bb (e->dest); !gsi_end_p (bi);
gsi_next (&bi))
{
gimple stmt = gsi_stmt (bi);
if (is_gimple_call (stmt)
/* Constant and pure calls are hardly used to signalize
something exceptional. */
&& gimple_has_side_effects (stmt))
{
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
break;
}
}
}
}
tree_predict_by_opcode (bb);
}
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
combine_predictions_for_bb (bb); combine_predictions_for_bb (bb);
...@@ -1722,6 +1723,31 @@ tree_estimate_probability (void) ...@@ -1722,6 +1723,31 @@ tree_estimate_probability (void)
estimate_bb_frequencies (); estimate_bb_frequencies ();
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_exit_edges (); remove_fake_exit_edges ();
}
/* Predict branch probabilities and estimate profile of the tree CFG.
This is the driver function for PASS_PROFILE. */
static unsigned int
tree_estimate_probability_driver (void)
{
unsigned nb_loops;
loop_optimizer_init (0);
if (dump_file && (dump_flags & TDF_DETAILS))
flow_loops_dump (dump_file, NULL, 0);
mark_irreducible_loops ();
nb_loops = number_of_loops ();
if (nb_loops > 1)
scev_initialize ();
tree_estimate_probability ();
if (nb_loops > 1)
scev_finalize ();
loop_optimizer_finalize (); loop_optimizer_finalize ();
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
gimple_dump_cfg (dump_file, dump_flags); gimple_dump_cfg (dump_file, dump_flags);
...@@ -2203,7 +2229,7 @@ struct gimple_opt_pass pass_profile = ...@@ -2203,7 +2229,7 @@ struct gimple_opt_pass pass_profile =
GIMPLE_PASS, GIMPLE_PASS,
"profile", /* name */ "profile", /* name */
gate_estimate_probability, /* gate */ gate_estimate_probability, /* gate */
tree_estimate_probability, /* execute */ tree_estimate_probability_driver, /* execute */
NULL, /* sub */ NULL, /* sub */
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
......
...@@ -40,5 +40,6 @@ extern int counts_to_freqs (void); ...@@ -40,5 +40,6 @@ extern int counts_to_freqs (void);
extern void estimate_bb_frequencies (void); extern void estimate_bb_frequencies (void);
extern const char *predictor_name (enum br_predictor); extern const char *predictor_name (enum br_predictor);
extern tree build_predict_expr (enum br_predictor, enum prediction); extern tree build_predict_expr (enum br_predictor, enum prediction);
extern void tree_estimate_probability (void);
#endif /* GCC_PREDICT_H */ #endif /* GCC_PREDICT_H */
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