From 688b6bc6943dc52195ca8748fdb741a4ad719bc0 Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 14 Nov 2017 09:18:35 +0000 Subject: [PATCH] * auto-profile.c (afdo_annotate_cfg): Use update_max_bb_count. * cgraphunit.c (cgraph_node::expand_thunk): Use update_max_bb_count. * ipa-utils.c (ipa_merge_profiles): Use update_max_bb_count. * lto-streamer-in.c (input_function): Use update_max_bb_count. * omp-expand.c (expand_omp_taskreg): Use update_max_bb_count. * predict.c (maybe_hot_frequency_p): Inline to ... (maybe_hot_count_p): ... here; rewrite to counts. (counts_to_freqs): Rename to ... (update_max_bb_count): ... this one. (expensive_function_p): Use counts. (estimate_bb_frequencies): Update. (rebuild_frequencies): Update. * predict.h (counts_to_freqs): Rename to ... (update_max_bb_count): ... this one. * profile.c (compute_branch_probabilities): Add debug info * tree-inline.c (expand_call_inline): Update debug info. (optimize_inline_calls): Use update_max_bb_count.. (tree_function_versioning): Use update_max_bb_count.. * value-prof.c (gimple_value_profile_transformations): Do not use update_max_bb_count. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254725 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 23 +++++++++++++++ gcc/auto-profile.c | 2 +- gcc/cgraphunit.c | 2 +- gcc/ipa-utils.c | 2 +- gcc/lto-streamer-in.c | 2 +- gcc/omp-expand.c | 2 +- gcc/predict.c | 81 ++++++++++++++++++++++++++------------------------- gcc/predict.h | 2 +- gcc/profile.c | 8 +++-- gcc/tree-inline.c | 16 +++++----- gcc/value-prof.c | 5 ---- 11 files changed, 85 insertions(+), 60 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9740447ab98..35cf703bd51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,28 @@ 2017-11-13 Jan Hubicka + * auto-profile.c (afdo_annotate_cfg): Use update_max_bb_count. + * cgraphunit.c (cgraph_node::expand_thunk): Use update_max_bb_count. + * ipa-utils.c (ipa_merge_profiles): Use update_max_bb_count. + * lto-streamer-in.c (input_function): Use update_max_bb_count. + * omp-expand.c (expand_omp_taskreg): Use update_max_bb_count. + * predict.c (maybe_hot_frequency_p): Inline to ... + (maybe_hot_count_p): ... here; rewrite to counts. + (counts_to_freqs): Rename to ... + (update_max_bb_count): ... this one. + (expensive_function_p): Use counts. + (estimate_bb_frequencies): Update. + (rebuild_frequencies): Update. + * predict.h (counts_to_freqs): Rename to ... + (update_max_bb_count): ... this one. + * profile.c (compute_branch_probabilities): Add debug info + * tree-inline.c (expand_call_inline): Update debug info. + (optimize_inline_calls): Use update_max_bb_count.. + (tree_function_versioning): Use update_max_bb_count.. + * value-prof.c (gimple_value_profile_transformations): + Do not use update_max_bb_count. + +2017-11-13 Jan Hubicka + * ipa-inline.c (compute_uninlined_call_time, compute_inlined_call_time): always use frequencies. diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c index f8c8871cf5e..5134a795331 100644 --- a/gcc/auto-profile.c +++ b/gcc/auto-profile.c @@ -1571,7 +1571,7 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) if (max_count > profile_count::zero ()) { afdo_calculate_branch_prob (&annotated_bb, &annotated_edge); - counts_to_freqs (); + update_max_bb_count (); profile_status_for_fn (cfun) = PROFILE_READ; } if (flag_value_profile_transformations) diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 3b68d646ffa..dec5c8b5736 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2026,7 +2026,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) } cfun->gimple_df->in_ssa_p = true; - counts_to_freqs (); + update_max_bb_count (); profile_status_for_fn (cfun) = cfg_count.initialized_p () && cfg_count.ipa_p () ? PROFILE_READ : PROFILE_GUESSED; diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 808db436b6a..c991bddd7dd 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -558,7 +558,7 @@ ipa_merge_profiles (struct cgraph_node *dst, } } push_cfun (dstcfun); - counts_to_freqs (); + update_max_bb_count (); compute_function_frequency (); pop_cfun (); for (e = dst->callees; e; e = e->next_callee) diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index acbbc9d6823..d852a3b3855 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1192,7 +1192,7 @@ input_function (tree fn_decl, struct data_in *data_in, gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest)); } - counts_to_freqs (); + update_max_bb_count (); fixup_call_stmt_edges (node, stmts); execute_all_ipa_stmt_fixups (node, stmts); diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 07856424f65..46d0bea6d42 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -1399,7 +1399,7 @@ expand_omp_taskreg (struct omp_region *region) if (optimize) optimize_omp_library_calls (entry_stmt); - counts_to_freqs (); + update_max_bb_count (); cgraph_edge::rebuild_edges (); /* Some EH regions might become dead, see PR34608. If diff --git a/gcc/predict.c b/gcc/predict.c index 56003a5db09..f490ec116ad 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -121,32 +121,6 @@ static const struct predictor_info predictor_info[]= { }; #undef DEF_PREDICTOR -/* Return TRUE if frequency FREQ is considered to be hot. */ - -static inline bool -maybe_hot_frequency_p (struct function *fun, int freq) -{ - struct cgraph_node *node = cgraph_node::get (fun->decl); - if (!profile_info || profile_status_for_fn (fun) != PROFILE_READ) - { - if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) - return false; - if (node->frequency == NODE_FREQUENCY_HOT) - return true; - } - if (profile_status_for_fn (fun) == PROFILE_ABSENT) - return true; - if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE - && freq < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.to_frequency (fun) * 2 / 3)) - return false; - if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0) - return false; - if (freq * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) - < ENTRY_BLOCK_PTR_FOR_FN (fun)->count.to_frequency (fun)) - return false; - return true; -} - static gcov_type min_count = -1; /* Determine the threshold for hot BB counts. */ @@ -179,10 +153,30 @@ maybe_hot_count_p (struct function *fun, profile_count count) { if (!count.initialized_p ()) return true; - if (!count.ipa_p ()) - return maybe_hot_frequency_p (fun, count.to_frequency (fun)); if (count.ipa () == profile_count::zero ()) return false; + if (!count.ipa_p ()) + { + struct cgraph_node *node = cgraph_node::get (fun->decl); + if (!profile_info || profile_status_for_fn (fun) != PROFILE_READ) + { + if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) + return false; + if (node->frequency == NODE_FREQUENCY_HOT) + return true; + } + if (profile_status_for_fn (fun) == PROFILE_ABSENT) + return true; + if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + && count < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (2, 3))) + return false; + if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0) + return false; + if (count.apply_scale (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION), 1) + < ENTRY_BLOCK_PTR_FOR_FN (fun)->count) + return false; + return true; + } /* Code executed at most once is not hot. */ if (count <= MAX (profile_info ? profile_info->runs : 1, 1)) return false; @@ -3317,7 +3311,7 @@ handle_missing_profiles (void) Return nonzero iff there was any nonzero execution count. */ bool -counts_to_freqs (void) +update_max_bb_count (void) { profile_count true_count_max = profile_count::uninitialized (); basic_block bb; @@ -3327,7 +3321,7 @@ counts_to_freqs (void) cfun->cfg->count_max = true_count_max; - return true_count_max.nonzero_p (); + return true_count_max.ipa ().nonzero_p (); } /* Return true if function is likely to be expensive, so there is no point to @@ -3338,30 +3332,37 @@ counts_to_freqs (void) bool expensive_function_p (int threshold) { - unsigned int sum = 0; basic_block bb; - unsigned int limit; /* We can not compute accurately for large thresholds due to scaled frequencies. */ gcc_assert (threshold <= BB_FREQ_MAX); - /* Frequencies are out of range. This either means that function contains - internal loop executing more than BB_FREQ_MAX times or profile feedback - is available and function has not been executed at all. */ - if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun) == 0) + /* If profile was scaled in a way entry block has count 0, then the function + is deifnitly taking a lot of time. */ + if (!ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.nonzero_p ()) return true; /* Maximally BB_FREQ_MAX^2 so overflow won't happen. */ - limit = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun) * threshold; + profile_count limit = ENTRY_BLOCK_PTR_FOR_FN + (cfun)->count.apply_scale (threshold, 1); + profile_count sum = profile_count::zero (); FOR_EACH_BB_FN (bb, cfun) { rtx_insn *insn; + if (!bb->count.initialized_p ()) + { + if (dump_file) + fprintf (dump_file, "Function is considered expensive because" + " count of bb %i is not initialized\n", bb->index); + return true; + } + FOR_BB_INSNS (bb, insn) if (active_insn_p (insn)) { - sum += bb->count.to_frequency (cfun); + sum += bb->count; if (sum > limit) return true; } @@ -3521,7 +3522,7 @@ estimate_bb_frequencies (bool force) determine_unlikely_bbs (); if (force || profile_status_for_fn (cfun) != PROFILE_READ - || !counts_to_freqs ()) + || !update_max_bb_count ()) { static int real_values_initialized = 0; @@ -3873,7 +3874,7 @@ rebuild_frequencies (void) loop_optimizer_finalize (); } else if (profile_status_for_fn (cfun) == PROFILE_READ) - counts_to_freqs (); + update_max_bb_count (); else gcc_unreachable (); timevar_pop (TV_REBUILD_FREQUENCIES); diff --git a/gcc/predict.h b/gcc/predict.h index 1b73ae28a49..24c604f5abf 100644 --- a/gcc/predict.h +++ b/gcc/predict.h @@ -89,7 +89,7 @@ extern void guess_outgoing_edge_probabilities (basic_block); extern void tree_guess_outgoing_edge_probabilities (basic_block); extern void tree_estimate_probability (bool); extern void handle_missing_profiles (void); -extern bool counts_to_freqs (void); +extern bool update_max_bb_count (void); extern bool expensive_function_p (int); extern void estimate_bb_frequencies (bool); extern void compute_function_frequency (void); diff --git a/gcc/profile.c b/gcc/profile.c index 2b30a9e6754..11170066cae 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -497,7 +497,11 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) /* Very simple sanity checks so we catch bugs in our profiling code. */ if (!profile_info) - return; + { + if (dump_file) + fprintf (dump_file, "Profile info is missing; giving up\n"); + return; + } bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun)); edge_gcov_counts = new hash_map; @@ -805,7 +809,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) delete edge_gcov_counts; edge_gcov_counts = NULL; - counts_to_freqs (); + update_max_bb_count (); if (dump_file) { diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 5c49214663f..d4aa5bed739 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-chkp.h" #include "stringpool.h" #include "attribs.h" +#include "sreal.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -4670,11 +4671,12 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf (dump_file, "Inlining "); - print_generic_expr (dump_file, id->src_fn); - fprintf (dump_file, " to "); - print_generic_expr (dump_file, id->dst_fn); - fprintf (dump_file, " with frequency %i\n", cg_edge->frequency ()); + fprintf (dump_file, "Inlining %s to %s with frequency %4.2f\n", + xstrdup_for_dump (id->src_node->dump_name ()), + xstrdup_for_dump (id->dst_node->dump_name ()), + cg_edge->sreal_frequency ().to_double ()); + id->src_node->dump (dump_file); + id->dst_node->dump (dump_file); } /* This is it. Duplicate the callee body. Assume callee is @@ -5057,7 +5059,7 @@ optimize_inline_calls (tree fn) } /* Fold queued statements. */ - counts_to_freqs (); + update_max_bb_count (); fold_marked_statements (last, id.statements_to_fold); delete id.statements_to_fold; @@ -6034,7 +6036,7 @@ tree_function_versioning (tree old_decl, tree new_decl, free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); - counts_to_freqs (); + update_max_bb_count (); fold_marked_statements (0, id.statements_to_fold); delete id.statements_to_fold; delete_unreachable_blocks_update_callgraph (&id); diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 85de3189f83..354279a6712 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -673,11 +673,6 @@ gimple_value_profile_transformations (void) } } - if (changed) - { - counts_to_freqs (); - } - return changed; } -- 2.11.4.GIT