More profile updating fixes

Christophe Lyon christophe.lyon@linaro.org
Mon Jun 5 19:20:00 GMT 2017


Hi,


On 5 June 2017 at 19:36, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> here are less trivial updates to profile code which I did not bundle into
> initial transition.  Those are not bugs in old code, just new code needs
> to track more.
>
> profile-bootstrapped/regtested x86_64-linux, will commit it shortly.
>         * 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.
> Index: cfgexpand.c
> ===================================================================
> --- cfgexpand.c (revision 248871)
> +++ cfgexpand.c (working copy)
> @@ -3850,8 +3850,8 @@ expand_gimple_tailcall (basic_block bb,
>
>    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: ipa-inline.c
> ===================================================================
> --- ipa-inline.c        (revision 248871)
> +++ ipa-inline.c        (working copy)
> @@ -912,7 +912,7 @@ want_inline_self_recursive_call_p (struc
>       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 (struc
>           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: profile-count.h
> ===================================================================
> --- profile-count.h     (revision 248871)
> +++ profile-count.h     (working copy)
> @@ -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: tree-inline.c
> ===================================================================
> --- tree-inline.c       (revision 248871)
> +++ tree-inline.c       (working copy)
> @@ -1763,7 +1763,8 @@ copy_bb (copy_body_data *id, basic_block
>    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, profi
>    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 c
>     */
>    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, prof
>    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: tree-ssa-threadupdate.c
> ===================================================================
> --- tree-ssa-threadupdate.c     (revision 248871)
> +++ tree-ssa-threadupdate.c     (working copy)
> @@ -1084,16 +1084,20 @@ clear_counts_path (struct redirection_da
>    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_da
>        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;
>      }
>  }
>

Your actual commit (r248885) also includes:
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index eaa1522..fb235e2 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -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;

which breaks the build with:
shrink-wrap.c:565: error: ‘struct edge_def’ has no member named ‘frequency’

Did you add shrink-wrap.c to your commit by accident?



More information about the Gcc-patches mailing list