cfgbuild.c (find_bb_boundaries): Initialize profile of split blocks.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 7 Jun 2017 06:42:43 +0000 (08:42 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 7 Jun 2017 06:42:43 +0000 (06:42 +0000)
* cfgbuild.c (find_bb_boundaries): Initialize profile of split blocks.
(compute_outgoing_frequencies): Also initialize zero counts.
(find_many_sub_basic_blocks): Do not produce uninitialized profile
around loops; preserve more of profile when nothing changes.

From-SVN: r248945

gcc/ChangeLog
gcc/cfgbuild.c

index 519fd6258515472209b87943fe8671f5b42fc723..3b2c8b9d6aac57a56b1e4cdebfe826c0d9db6ba3 100644 (file)
@@ -1,3 +1,10 @@
+2017-06-06  Jan Hubicka  <hubicka@ucw.cz>
+
+       * cfgbuild.c (find_bb_boundaries): Initialize profile of split blocks.
+       (compute_outgoing_frequencies): Also initialize zero counts.
+       (find_many_sub_basic_blocks): Do not produce uninitialized profile
+       around loops; preserve more of profile when nothing changes.
+
 2017-06-06  Jim Wilson  <jim.wilson@linaro.org>
 
        * config/aarch64/aarch64-cost-tables.h (qdf24xx_extra_costs): Move to
index a4004f87e939e33c5999dee9c7a0fcb05a0479b2..f4a4d088251bf0c39557064d95b9aacde19cd280 100644 (file)
@@ -475,6 +475,10 @@ find_bb_boundaries (basic_block bb)
 
          bb = fallthru->dest;
          remove_edge (fallthru);
+         /* BB is unreachable at this point - we need to determine its profile
+            once edges are built.  */
+         bb->frequency = 0;
+         bb->count = profile_count::uninitialized ();
          flow_transfer_insn = NULL;
          if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn))
            make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, 0);
@@ -577,7 +581,7 @@ compute_outgoing_frequencies (basic_block b)
         guess_outgoing_edge_probabilities (b);
     }
 
-  if (b->count > profile_count::zero ())
+  if (b->count.initialized_p ())
     FOR_EACH_EDGE (e, ei, b->succs)
       e->count = b->count.apply_probability (e->probability);
 }
@@ -590,6 +594,9 @@ void
 find_many_sub_basic_blocks (sbitmap blocks)
 {
   basic_block bb, min, max;
+  bool found = false;
+  auto_vec<unsigned int> n_succs;
+  n_succs.safe_grow_cleared (last_basic_block_for_fn (cfun));
 
   FOR_EACH_BB_FN (bb, cfun)
     SET_STATE (bb,
@@ -597,11 +604,24 @@ find_many_sub_basic_blocks (sbitmap blocks)
 
   FOR_EACH_BB_FN (bb, cfun)
     if (STATE (bb) == BLOCK_TO_SPLIT)
-      find_bb_boundaries (bb);
+      {
+       int n = last_basic_block_for_fn (cfun);
+       unsigned int ns = EDGE_COUNT (bb->succs);
+
+        find_bb_boundaries (bb);
+       if (n == last_basic_block_for_fn (cfun) && ns == EDGE_COUNT (bb->succs))
+         n_succs[bb->index] = EDGE_COUNT (bb->succs);
+      }
 
   FOR_EACH_BB_FN (bb, cfun)
     if (STATE (bb) != BLOCK_ORIGINAL)
-      break;
+      {
+       found = true;
+        break;
+      }
+
+  if (!found)
+    return;
 
   min = max = bb;
   for (; bb != EXIT_BLOCK_PTR_FOR_FN (cfun); bb = bb->next_bb)
@@ -624,14 +644,37 @@ find_many_sub_basic_blocks (sbitmap blocks)
          continue;
        if (STATE (bb) == BLOCK_NEW)
          {
+           bool initialized_src = false, uninitialized_src = false;
            bb->count = profile_count::zero ();
            bb->frequency = 0;
            FOR_EACH_EDGE (e, ei, bb->preds)
              {
-               bb->count += e->count;
+               if (e->count.initialized_p ())
+                 {
+                   bb->count += e->count;
+                   initialized_src = true;
+                 }
+               else
+                 uninitialized_src = false;
                bb->frequency += EDGE_FREQUENCY (e);
              }
+           /* When some edges are missing with read profile, this is
+              most likely because RTL expansion introduced loop.
+              When profile is guessed we may have BB that is reachable
+              from unlikely path as well as from normal path.
+
+              TODO: We should handle loops created during BB expansion
+              correctly here.  For now we assume all those loop to cycle
+              precisely once.  */
+           if (!initialized_src
+               || (uninitialized_src
+                    && profile_status_for_fn (cfun) != PROFILE_READ))
+             bb->count = profile_count::uninitialized ();
          }
+       else
+         /* If nothing changed, there is no need to create new BBs.  */
+         if (EDGE_COUNT (bb->succs) == n_succs[bb->index])
+           continue;
 
        compute_outgoing_frequencies (bb);
       }