cfgexpand.c (expand_gimple_tailcall): Initialize profile of new edge.
authorJan Hubicka <hubicka@ucw.cz>
Mon, 5 Jun 2017 17:41:32 +0000 (19:41 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 5 Jun 2017 17:41:32 +0000 (17:41 +0000)
* cfgexpand.c (expand_gimple_tailcall): Initialize profile of
new edge.
* ipa-inline.c (want_inline_self_recursive_call_p): Watch for missing
profile in callgraph edge.
* profile-count.h (apply_probability): If THIS is 0, then result is 0
(apply_scale): Likewise.
* tree-inline.c (copy_bb, copy_edges_for_bb, copy_cfg_body):
Also scale profile when inlining function with zero profile.
(initialize_cfun): Update exit block profile even when it is zero.
* tree-ssa-threadupdate.c (clear_counts_path): Handle correctly case
when profile is read.

From-SVN: r248885

gcc/ChangeLog
gcc/cfgexpand.c
gcc/ipa-inline.c
gcc/profile-count.h
gcc/shrink-wrap.c
gcc/tree-inline.c
gcc/tree-ssa-threadupdate.c

index cc8112d4e01cbc2d37234e839e6fee597313c99f..15841daac597611fddce688cc5e3abbfd81b640d 100644 (file)
@@ -1,3 +1,17 @@
+2017-06-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       * cfgexpand.c (expand_gimple_tailcall): Initialize profile of
+       new edge.
+       * ipa-inline.c (want_inline_self_recursive_call_p): Watch for missing
+       profile in callgraph edge.
+       * profile-count.h (apply_probability): If THIS is 0, then result is 0
+       (apply_scale): Likewise.
+       * tree-inline.c (copy_bb, copy_edges_for_bb, copy_cfg_body):
+       Also scale profile when inlining function with zero profile.
+       (initialize_cfun): Update exit block profile even when it is zero.
+       * tree-ssa-threadupdate.c (clear_counts_path): Handle correctly case
+       when profile is read.
+
 2017-06-05  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000.c (toplevel): Include attribs.h.
index 3261fce8843c62f80efaf4b0529bdd77ea3e40be..c1f80727d3060f34bdb96cf7f2a9cbb1a93da84e 100644 (file)
@@ -3850,8 +3850,8 @@ expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru)
 
   e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_ABNORMAL
                 | EDGE_SIBCALL);
-  e->probability += probability;
-  e->count += count;
+  e->probability = probability;
+  e->count = count;
   BB_END (bb) = last;
   update_bb_for_insn (bb);
 
index 8900556ef10d891c9f26a4c9aac894a7c483de99..64c9ebd6692f54c253847e8b7a38eadee0818acc 100644 (file)
@@ -912,7 +912,7 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge,
      methods.  */
   else
     {
-      if (max_count > profile_count::zero ()
+      if (max_count > profile_count::zero () && edge->count.initialized_p ()
          && (edge->count.to_gcov_type () * 100
              / outer_node->count.to_gcov_type ()
              <= PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY)))
@@ -920,7 +920,8 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge,
          reason = "profile of recursive call is too small";
          want_inline = false;
        }
-      else if (max_count == profile_count::zero ()
+      else if ((max_count == profile_count::zero ()
+               || !edge->count.initialized_p ())
               && (edge->frequency * 100 / caller_freq
                   <= PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY)))
        {
index 2ac7f32278d0c9b99cf419dded447e9fadaffd46..e7815dbcfcb64b57a5cd26d2b3491346b333ed6e 100644 (file)
@@ -221,6 +221,8 @@ public:
   profile_count apply_probability (int prob) const
     {
       gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
+      if (*this == profile_count::zero ())
+       return *this;
       if (!initialized_p ())
        return profile_count::uninitialized ();
       profile_count ret;
@@ -230,6 +232,8 @@ public:
   /* Return *THIS * NUM / DEN.  */
   profile_count apply_scale (int64_t num, int64_t den) const
     {
+      if (*this == profile_count::zero ())
+       return *this;
       if (!initialized_p ())
        return profile_count::uninitialized ();
       profile_count ret;
@@ -243,7 +247,7 @@ public:
     }
   profile_count apply_scale (profile_count num, profile_count den) const
     {
-      if (*this == profile_count::zero ())
+      if (*this == profile_count::zero () || num == profile_count::zero ())
        return profile_count::zero ();
       if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
        return profile_count::uninitialized ();
index eaa1522bb0db28ce90905f9434e28175b09b74cf..fb235e2bc9ffb59e2e05a80f4e266537ea0a8d7c 100644 (file)
@@ -561,9 +561,11 @@ handle_simple_exit (edge e)
       BB_END (old_bb) = end;
 
       redirect_edge_succ (e, new_bb);
+      new_bb->count = e->count;
+      new_bb->frequency = e->frequency;
       e->flags |= EDGE_FALLTHRU;
 
-      e = make_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+      e = make_single_succ_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
     }
 
   e->flags &= ~EDGE_FALLTHRU;
index 7f20cdc7f8e0211a3092a0593b9c851c43fee669..329800185ec6624d77a060323a928a12bbc91130 100644 (file)
@@ -1763,7 +1763,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
   tree decl;
   gcov_type freq;
   basic_block prev;
-  bool scale = num.initialized_p () && den.initialized_p () && den > 0;
+  bool scale = num.initialized_p ()
+              && (den > 0 || num == profile_count::zero ());
 
   /* Search for previous copied basic block.  */
   prev = bb->prev_bb;
@@ -2211,7 +2212,8 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
   gimple_stmt_iterator si;
   int flags;
   bool need_debug_cleanup = false;
-  bool scale = num.initialized_p () && den.initialized_p () && den > 0;
+  bool scale = num.initialized_p ()
+              && (den > 0 || num == profile_count::zero ());
 
   /* Use the indices from the original blocks to create edges for the
      new ones.  */
@@ -2472,7 +2474,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count)
    */
   if (ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.initialized_p ()
       && count.initialized_p ()
-      && ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count > 0)
+      && ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.initialized_p ())
     {
       ENTRY_BLOCK_PTR_FOR_FN (cfun)->count =
        ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count,
@@ -2683,7 +2685,8 @@ copy_cfg_body (copy_body_data * id, profile_count count, int frequency_scale,
   profile_count incoming_count = profile_count::zero ();
   profile_count num = count;
   profile_count den = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count;
-  bool scale = num.initialized_p () && den.initialized_p () && den > 0;
+  bool scale = num.initialized_p ()
+              && (den > 0 || num == profile_count::zero ());
 
   /* This can happen for COMDAT routines that end up with 0 counts
      despite being called (see the comments for handle_missing_profiles()
index a77c279b41b1cf3c4f286cc319e908442704060f..df4c6def78af9cdc6fe8e19caae3c8cb8a2701c1 100644 (file)
@@ -1084,16 +1084,20 @@ clear_counts_path (struct redirection_data *rd)
   vec<jump_thread_edge *> *path = THREAD_PATH (e);
   edge ein, esucc;
   edge_iterator ei;
+  profile_count val = profile_count::uninitialized ();
+  if (profile_status_for_fn (cfun) == PROFILE_READ)
+    val = profile_count::zero ();
+
   FOR_EACH_EDGE (ein, ei, e->dest->preds)
-    ein->count = profile_count::uninitialized ();
+    ein->count = val;
 
   /* First clear counts along original path.  */
   for (unsigned int i = 1; i < path->length (); i++)
     {
       edge epath = (*path)[i]->e;
       FOR_EACH_EDGE (esucc, ei, epath->src->succs)
-       esucc->count = profile_count::uninitialized ();
-      epath->src->count = profile_count::uninitialized ();
+       esucc->count = val;
+      epath->src->count = val;
     }
   /* Also need to clear the counts along duplicated path.  */
   for (unsigned int i = 0; i < 2; i++)
@@ -1102,8 +1106,8 @@ clear_counts_path (struct redirection_data *rd)
       if (!dup)
        continue;
       FOR_EACH_EDGE (esucc, ei, dup->succs)
-       esucc->count = profile_count::uninitialized ();
-      dup->count = profile_count::uninitialized ();
+       esucc->count = val;
+      dup->count = val;
     }
 }