diff options
author | Jan Hubicka <jh@suse.cz> | 2018-11-28 21:48:53 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2018-11-28 20:48:53 +0000 |
commit | 410902c31caa82cf414f020b5db51ddc20159f20 (patch) | |
tree | 25f6fe6b41b104035d34d83de12cc84a6419e7cd /gcc/predict.c | |
parent | ad42aa96b6ca0695dce4925d9655938fc1900edf (diff) | |
download | gcc-410902c31caa82cf414f020b5db51ddc20159f20.tar.gz |
predict.c (determine_unlikely_bbs): Forward declare...
* predict.c (determine_unlikely_bbs): Forward declare; also determine
edges that are always known to be taken because it is only likely
edge out of given BB.
(tree_estimate_probability): Call before profile guessing to get bit
of extra precision.
* gcc.dg/predict-13.c: Update template.
* gcc.dg/predict-13b.c: New testcase.
* gcc.dg/predict-22.c: New testcase.
* gcc.dg/tree-ssa/ipa-split-4.c: Change abort to other function to
get sane profile.
From-SVN: r266587
Diffstat (limited to 'gcc/predict.c')
-rw-r--r-- | gcc/predict.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/gcc/predict.c b/gcc/predict.c index 8482737ab27..5ad252c2d39 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -93,6 +93,7 @@ static void predict_paths_leading_to_edge (edge, enum br_predictor, struct loop *in_loop = NULL); static bool can_predict_insn_p (const rtx_insn *); static HOST_WIDE_INT get_predictor_value (br_predictor, HOST_WIDE_INT); +static void determine_unlikely_bbs (); /* Information we hold about each branch predictor. Filled using information from predict.def. */ @@ -3063,6 +3064,9 @@ tree_estimate_probability (bool dry_run) preheaders. */ create_preheaders (CP_SIMPLE_PREHEADERS); calculate_dominance_info (CDI_POST_DOMINATORS); + /* Decide which edges are known to be unlikely. This improves later + branch prediction. */ + determine_unlikely_bbs (); bb_predictions = new hash_map<const_basic_block, edge_prediction *>; tree_bb_level_predictions (); @@ -3768,17 +3772,40 @@ determine_unlikely_bbs () } /* Finally all edges from non-0 regions to 0 are unlikely. */ FOR_ALL_BB_FN (bb, cfun) - if (!(bb->count == profile_count::zero ())) + { + if (!(bb->count == profile_count::zero ())) + FOR_EACH_EDGE (e, ei, bb->succs) + if (!(e->probability == profile_probability::never ()) + && e->dest->count == profile_count::zero ()) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Edge %i->%i is unlikely because " + "it enters unlikely block\n", + bb->index, e->dest->index); + e->probability = profile_probability::never (); + } + + edge other = NULL; + FOR_EACH_EDGE (e, ei, bb->succs) - if (!(e->probability == profile_probability::never ()) - && e->dest->count == profile_count::zero ()) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Edge %i->%i is unlikely because " - "it enters unlikely block\n", - bb->index, e->dest->index); - e->probability = profile_probability::never (); - } + if (e->probability == profile_probability::never ()) + ; + else if (other) + { + other = NULL; + break; + } + else + other = e; + if (other + && !(other->probability == profile_probability::always ())) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Edge %i->%i is locally likely\n", + bb->index, other->dest->index); + other->probability = profile_probability::always (); + } + } if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ()) cgraph_node::get (current_function_decl)->count = profile_count::zero (); } |