From: Jan Hubicka Date: Wed, 28 Nov 2018 20:48:53 +0000 (+0100) Subject: predict.c (determine_unlikely_bbs): Forward declare... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=410902c31caa82cf414f020b5db51ddc20159f20;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bc49105e219..6607cd7c710 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-11-28 Jan Hubicka + + * 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. + 2018-11-28 Jan Hubicka * tree-ssa-ifcombine.c (update_profile_after_ifcombine): Handle 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; 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 (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd76bc72070..575c6316c89 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-11-28 Jan Hubicka + + * 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. + 2018-11-28 Marek Polacek PR c++/88222 - ICE with bit-field with invalid type. diff --git a/gcc/testsuite/gcc.dg/predict-13.c b/gcc/testsuite/gcc.dg/predict-13.c index c6da45f8127..9602e789dc2 100644 --- a/gcc/testsuite/gcc.dg/predict-13.c +++ b/gcc/testsuite/gcc.dg/predict-13.c @@ -20,5 +20,5 @@ int main(int argc, char **argv) return 10; } -/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.30%" 3 "profile_estimate"} } */ -/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.05%" 2 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "33.33%" 3 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "0.00%" 3 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-13b.c b/gcc/testsuite/gcc.dg/predict-13b.c new file mode 100644 index 00000000000..7f4722fcc52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/predict-13b.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-profile_estimate" } */ + +void exit(int); + +int main(int argc, char **argv) +{ + switch (argc) + { + case 1: + return 1; + case 2: + return 2; + case 3: + exit(1); + case 4: + exit(2); + default: + return 5; + } + + return 10; +} + +/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.30%" 3 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.05%" 2 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-22.c b/gcc/testsuite/gcc.dg/predict-22.c new file mode 100644 index 00000000000..0d50c81ebce --- /dev/null +++ b/gcc/testsuite/gcc.dg/predict-22.c @@ -0,0 +1,59 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-rtl-bbpart-details-blocks -freorder-blocks-and-partition" } */ +volatile int v; +void bar (void) __attribute__((leaf, cold)); +void baz (int *); + +void +foo (int x, int y, int z) +{ + static int f __attribute__((section ("mysection"))); + f = 1; + if (__builtin_expect (x, 0)) + if (__builtin_expect (y, 0)) + if (__builtin_expect (z, 0)) + { + f = 2; + bar (); + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + v += 1; + v *= 2; + v /= 2; + v -= 1; + f = 3; + __builtin_abort (); + } + f = 4; + f = 5; + baz (&f); +} +/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "count 0," 1 "optimized"} } */ +/* { dg-final { scan-rtl-dump-times "COLD_PARTITION" 1 "bbpart"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c index 437ddec966f..43537b6714c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c @@ -1,14 +1,14 @@ /* { dg-do compile } */ /* { dg-options "-O3 -fdump-tree-fnsplit" } */ int make_me_big (void); -void abort (void); +void do_work (void); int split_me (int a) { if (__builtin_expect(a<10, 1)) { - abort (); + do_work (); } else {