summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2018-11-28 21:48:53 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2018-11-28 20:48:53 +0000
commit410902c31caa82cf414f020b5db51ddc20159f20 (patch)
tree25f6fe6b41b104035d34d83de12cc84a6419e7cd
parentad42aa96b6ca0695dce4925d9655938fc1900edf (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/predict.c47
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/predict-13.c4
-rw-r--r--gcc/testsuite/gcc.dg/predict-13b.c26
-rw-r--r--gcc/testsuite/gcc.dg/predict-22.c59
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c4
7 files changed, 142 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bc49105e219..6607cd7c710 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2018-11-28 Jan Hubicka <jh@suse.cz>
+ * 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 <jh@suse.cz>
+
* tree-ssa-ifcombine.c (update_profile_after_ifcombine): Handle
profile_probability::always better.
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 ();
}
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 <jh@suse.cz>
+
+ * 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 <polacek@redhat.com>
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
{