Message ID | CAAe5K+XHKWOkZEaavJkFEfhWME4qKg_ByuXSrzxhKjgCu-QpWQ@mail.gmail.com |
---|---|
State | New |
Headers | show |
> Here is the patch updated to use the new parameter from r203830. > Passed bootstrap and regression tests. > > 2013-10-18 Jan Hubicka <jh@suse.cz> > Teresa Johnson <tejohnson@google.com> > > * predict.c (handle_missing_profiles): New function. > (counts_to_freqs): Don't overwrite estimated frequencies > when function has no profile counts. > * predict.h (handle_missing_profiles): Declare. > * tree-profile.c (tree_profiling): Invoke handle_missing_profiles. > > Index: predict.c > =================================================================== > --- predict.c (revision 203830) > +++ predict.c (working copy) > @@ -2758,6 +2758,40 @@ estimate_loops (void) > BITMAP_FREE (tovisit); > } > You need block comment. It should explain the problem of COMDATs and how they are handled. It is not an obvious thing. > +void > +handle_missing_profiles (void) > +{ > + struct cgraph_node *node; > + int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION); extra line > + /* See if 0 count function has non-0 count callers. In this case we > + lost some profile. Drop its function profile to PROFILE_GUESSED. */ > + FOR_EACH_DEFINED_FUNCTION (node) > + { > + struct cgraph_edge *e; > + gcov_type call_count = 0; > + struct function *fn = DECL_STRUCT_FUNCTION (node->symbol.decl); Extra line > + if (node->count) > + continue; > + for (e = node->callers; e; e = e->next_caller) > + call_count += e->count; What about checking if the sum is way off even for non-0 counts. I.e. for case where function was inlined to some calls but not to others? In that case we may want to scale up the counts (with some resonable care for capping) Also I think the code really should propagate - i.e. have simple worklist and look for functions that are COMDAT and are called by other COMDAT functions where we decided to drop the profile. Having non-trivial chains of comdats is common thing. What about outputting user visible warning/error on the incosnsistency when no COMDAT function is involved same way as we do for BB profile? Honza
Index: predict.c =================================================================== --- predict.c (revision 203830) +++ predict.c (working copy) @@ -2758,6 +2758,40 @@ estimate_loops (void) BITMAP_FREE (tovisit); } +void +handle_missing_profiles (void) +{ + struct cgraph_node *node; + int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION); + /* See if 0 count function has non-0 count callers. In this case we + lost some profile. Drop its function profile to PROFILE_GUESSED. */ + FOR_EACH_DEFINED_FUNCTION (node) + { + struct cgraph_edge *e; + gcov_type call_count = 0; + struct function *fn = DECL_STRUCT_FUNCTION (node->symbol.decl); + if (node->count) + continue; + for (e = node->callers; e; e = e->next_caller) + call_count += e->count; + if (call_count + && fn && fn->cfg + && (call_count * unlikely_count_fraction >= profile_info->runs)) + { + bool maybe_hot = maybe_hot_count_p (NULL, call_count); + if (dump_file) + fprintf (dump_file, + "Dropping 0 profile for %s/%i. %s based on calls.\n", + cgraph_node_name (node), node->symbol.order, + maybe_hot ? "Function is hot" : "Function is normal"); + profile_status_for_function (fn) + = (flag_guess_branch_prob ? PROFILE_GUESSED : PROFILE_ABSENT); + node->frequency + = maybe_hot ? NODE_FREQUENCY_HOT : NODE_FREQUENCY_NORMAL; + } + } +} + /* Convert counts measured by profile driven feedback to frequencies. Return nonzero iff there was any nonzero execution count. */ @@ -2767,6 +2801,9 @@ counts_to_freqs (void) gcov_type count_max, true_count_max = 0; basic_block bb; + if (!ENTRY_BLOCK_PTR->count) + return 0; + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) true_count_max = MAX (bb->count, true_count_max); Index: predict.h =================================================================== --- predict.h (revision 203830) +++ predict.h (working copy) @@ -37,6 +37,7 @@ enum prediction extern void predict_insn_def (rtx, enum br_predictor, enum prediction); extern int counts_to_freqs (void); +extern void handle_missing_profiles (void); extern void estimate_bb_frequencies (bool); extern const char *predictor_name (enum br_predictor); extern tree build_predict_expr (enum br_predictor, enum prediction); Index: tree-profile.c =================================================================== --- tree-profile.c (revision 203830) +++ tree-profile.c (working copy) @@ -607,6 +607,8 @@ tree_profiling (void) pop_cfun (); } + handle_missing_profiles (); + del_node_map (); return 0; }