ipa-split.c (struct split_point): Add count.
authorJan Hubicka <hubicka@ucw.cz>
Tue, 14 Nov 2017 09:06:12 +0000 (10:06 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 14 Nov 2017 09:06:12 +0000 (09:06 +0000)
* ipa-split.c (struct split_point): Add count.
(consider_split): Do not compute incoming frequency; compute incoming
count and store it to split_point.
(split_function): Set count of the call to split part correctly.

* testsuite/gcc.dg/tree-ssa/fnsplit-2.c: New testcase.

From-SVN: r254720

gcc/ChangeLog
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c
gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c [new file with mode: 0644]

index 13a60e8ed7d4676a108ea448edd6bf9465369a09..6d719d316887b1860bac62c1db3e64b5796f09eb 100644 (file)
@@ -1,3 +1,10 @@
+2017-11-13  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-split.c (struct split_point): Add count.
+       (consider_split): Do not compute incoming frequency; compute incoming
+       count and store it to split_point.
+       (split_function): Set count of the call to split part correctly.
+
 2017-11-13  Carl Love  <cel@us.ibm.com>
 
        * config/rs6000/altivec.md (altivec_vsumsws_be): Add define_expand.
index 252ea053e2aa357224c390ff7efe64a1ebf5f4c6..9f893915c1749b5121f741f912a73290d21da330 100644 (file)
@@ -129,6 +129,10 @@ struct split_point
   /* Basic block where we split (that will become entry point of new function.  */
   basic_block entry_bb;
 
+  /* Count for entering the split part.
+     This is not count of the entry_bb because it may be in loop.  */
+  profile_count count;
+
   /* Basic blocks we are splitting away.  */
   bitmap split_bbs;
 
@@ -426,7 +430,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
   edge_iterator ei;
   gphi_iterator bsi;
   unsigned int i;
-  int incoming_freq = 0;
   tree retval;
   tree retbnd;
   bool back_edge = false;
@@ -434,18 +437,21 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_split_point (dump_file, current);
 
+  current->count = profile_count::zero ();
   FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
     {
       if (e->flags & EDGE_DFS_BACK)
        back_edge = true;
       if (!bitmap_bit_p (current->split_bbs, e->src->index))
-        incoming_freq += EDGE_FREQUENCY (e);
+       current->count += e->count ();
     }
 
-  /* Do not split when we would end up calling function anyway.  */
-  if (incoming_freq
-      >= (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun)
-         * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
+  /* Do not split when we would end up calling function anyway.
+     Compares are three state, use !(...<...) to also give up when outcome
+     is unknown.  */
+  if (!(current->count
+       < (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale
+          (PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY), 100))))
     {
       /* When profile is guessed, we can not expect it to give us
         realistic estimate on likelyness of function taking the
@@ -454,14 +460,17 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
         is likely noticeable win.  */
       if (back_edge
          && profile_status_for_fn (cfun) != PROFILE_READ
-         && incoming_freq
-                < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun))
+         && current->count
+                < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file,
-                    "  Split before loop, accepting despite low frequencies %i %i.\n",
-                    incoming_freq,
-                    ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun));
+           {
+             fprintf (dump_file,
+                      "  Split before loop, accepting despite low counts");
+             current->count.dump (dump_file);
+             fprintf (dump_file, " ");
+             ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.dump (dump_file);
+           }
        }
       else
        {
@@ -711,14 +720,13 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "  Accepted!\n");
 
-  /* At the moment chose split point with lowest frequency and that leaves
+  /* At the moment chose split point with lowest count and that leaves
      out smallest size of header.
      In future we might re-consider this heuristics.  */
   if (!best_split_point.split_bbs
-      || best_split_point.entry_bb->count.to_frequency (cfun)
-        > current->entry_bb->count.to_frequency (cfun)
-      || (best_split_point.entry_bb->count.to_frequency (cfun)
-         == current->entry_bb->count.to_frequency (cfun)
+      || best_split_point.count
+        > current->count
+      || (best_split_point.count == current->count 
          && best_split_point.split_size < current->split_size))
        
     {
@@ -1446,6 +1454,7 @@ split_function (basic_block return_bb, struct split_point *split_point,
       }
     else
       break;
+  call_bb->count = split_point->count;
   e = split_block (split_point->entry_bb, last_stmt);
   remove_edge (e);
 
index 3c4c37d517bf464c4d7890685030a32915b5e71a..11a4a121f13a368f58a4dc97ee8327275eb3c9ce 100644 (file)
@@ -1,3 +1,7 @@
+2017-11-13  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gcc.dg/tree-ssa/fnsplit-2.c: New testcase.
+
 2017-11-13  Fritz Reese <fritzoreese@gmail.com>
 
        PR fortran/78240
index ad5fc101cd8ee9a137a00d6bfcebdf5216b950f1..1b9696dcb117be38913423b82299a0ec71e97ee2 100644 (file)
@@ -19,4 +19,5 @@ main(void)
   return 0;
 }
 /* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */
+/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "fnsplit"} } */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c
new file mode 100644 (file)
index 0000000..c00213c
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fnsplit-blocks-details" } */
+void q (void);
+int b;
+void test (void);
+void
+split_me (int *a)
+{
+  if (__builtin_expect (a==0, 0))
+    do
+    {
+      test();
+      test();
+      test();
+      test();
+      test();
+    }
+    while (b);
+  else
+    q();
+}
+
+int
+main(void)
+{
+  int i;
+  for (i = 0; i < 1000; i++)
+    split_me(&i);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */
+/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "fnsplit"} } */