predict.c (determine_unlikely_bbs): Forward declare...
authorJan Hubicka <jh@suse.cz>
Wed, 28 Nov 2018 20:48:53 +0000 (21:48 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 28 Nov 2018 20:48:53 +0000 (20:48 +0000)
* 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

gcc/ChangeLog
gcc/predict.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/predict-13.c
gcc/testsuite/gcc.dg/predict-13b.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/predict-22.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ipa-split-4.c

index bc49105e219f5107452ce4c842a16299b411a0c3..6607cd7c7102021c6121b0f9d2eab0b2178a8dfd 100644 (file)
@@ -1,3 +1,11 @@
+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
index 8482737ab2722dcbda186146d7209def3dc0ae2c..5ad252c2d3947dd7956113c4388cfbfc25cf903e 100644 (file)
@@ -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 ();
 }
index fd76bc72070959e7de07f4837b6c5d1b99bbe2c6..575c6316c89ef4c58734185fa83891e2c7e91012 100644 (file)
@@ -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.
index c6da45f8127b16ed8482733d30fdefdba6e599eb..9602e789dc2707fb3874d0d23ade3ce8a3c5fe1f 100644 (file)
@@ -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 (file)
index 0000000..7f4722f
--- /dev/null
@@ -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 (file)
index 0000000..0d50c81
--- /dev/null
@@ -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"} } */
index 437ddec966fe35ddb4df0d33af6d727c84c35463..43537b6714cd3b52dbe5a2f6095cd9bd3c03d9d8 100644 (file)
@@ -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
     {