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
This commit is contained in:
Sebastian Pop 2009-08-12 14:19:33 +00:00 committed by Sebastian Pop
parent 87d4d0ee25
commit 8e88f9fddf
6 changed files with 151 additions and 90 deletions

View File

@ -1,3 +1,17 @@
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.

View File

@ -1,3 +1,17 @@
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.

View File

@ -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) \
$(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_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 \
graphite-scop-detection.h graphite-clast-to-gimple.h \
graphite-poly.h graphite-sese-to-poly.h

View File

@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "gimple.h"
#include "sese.h"
#include "predict.h"
#ifdef HAVE_cloog
@ -229,7 +230,12 @@ static void
graphite_finalize (bool 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 ();
free_original_copy_tables ();

View File

@ -916,8 +916,6 @@ predict_loops (void)
loop_iterator li;
struct loop *loop;
scev_initialize ();
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
FOR_EACH_LOOP (li, loop, 0)
@ -1040,8 +1038,6 @@ predict_loops (void)
/* Free basic blocks from get_loop_body. */
free (bbs);
}
scev_finalize ();
}
/* Attempt to predict probabilities of BB outgoing edges using local
@ -1608,16 +1604,96 @@ assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value,
}
#endif
/* Predict branch probabilities and estimate profile of the tree CFG. */
static unsigned int
/* Predict branch probabilities and estimate profile for basic block BB. */
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)
{
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 ();
connect_infinite_loops_to_exit ();
/* We use loop_niter_by_eval, which requires that the loops have
@ -1627,89 +1703,14 @@ tree_estimate_probability (void)
bb_predictions = pointer_map_create ();
tree_bb_level_predictions ();
mark_irreducible_loops ();
record_loop_exits ();
if (number_of_loops () > 1)
predict_loops ();
FOR_EACH_BB (bb)
{
edge e;
edge_iterator ei;
gimple last;
tree_estimate_probability_bb (bb);
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)
combine_predictions_for_bb (bb);
@ -1722,6 +1723,31 @@ tree_estimate_probability (void)
estimate_bb_frequencies ();
free_dominance_info (CDI_POST_DOMINATORS);
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 ();
if (dump_file && (dump_flags & TDF_DETAILS))
gimple_dump_cfg (dump_file, dump_flags);
@ -2203,7 +2229,7 @@ struct gimple_opt_pass pass_profile =
GIMPLE_PASS,
"profile", /* name */
gate_estimate_probability, /* gate */
tree_estimate_probability, /* execute */
tree_estimate_probability_driver, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */

View File

@ -40,5 +40,6 @@ extern int counts_to_freqs (void);
extern void estimate_bb_frequencies (void);
extern const char *predictor_name (enum br_predictor);
extern tree build_predict_expr (enum br_predictor, enum prediction);
extern void tree_estimate_probability (void);
#endif /* GCC_PREDICT_H */