* 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.
From-SVN: r254725
+2017-11-13 Jan Hubicka <hubicka@ucw.cz>
+
+ * 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 <hubicka@ucw.cz>
* ipa-inline.c (compute_uninlined_call_time, compute_inlined_call_time):
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)
}
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;
}
}
push_cfun (dstcfun);
- counts_to_freqs ();
+ update_max_bb_count ();
compute_function_frequency ();
pop_cfun ();
for (e = dst->callees; e; e = e->next_callee)
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);
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
};
#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. */
{
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;
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;
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
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;
}
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;
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);
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);
/* 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<edge,gcov_type>;
delete edge_gcov_counts;
edge_gcov_counts = NULL;
- counts_to_freqs ();
+ update_max_bb_count ();
if (dump_file)
{
#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. */
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
}
/* Fold queued statements. */
- counts_to_freqs ();
+ update_max_bb_count ();
fold_marked_statements (last, id.statements_to_fold);
delete id.statements_to_fold;
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);
}
}
- if (changed)
- {
- counts_to_freqs ();
- }
-
return changed;
}