From 151b9ff52a095baa99b7cd3f392f82b221d81f98 Mon Sep 17 00:00:00 2001 From: hubicka Date: Fri, 10 Nov 2017 20:14:52 +0000 Subject: * auto-profile.c (afdo_indirect_call): Drop frequency. * cgraph.c (symbol_table::create_edge): Drop frequency argument. (cgraph_node::create_edge): Drop frequency argument. (cgraph_node::create_indirect_edge): Drop frequency argument. (cgraph_edge::make_speculative): Drop frequency arguments. (cgraph_edge::resolve_speculation): Do not update frequencies (cgraph_edge::dump_edge_flags): Do not dump frequency. (cgraph_node::dump): Check consistency in IPA mode. (cgraph_edge::maybe_hot_p): Use IPA counter. (cgraph_edge::verify_count_and_frequency): Rename to ... (cgraph_edge::verify_count): ... this one; drop frequency checking. (cgraph_node::verify_node): Update. * cgraph.h (struct cgraph_edge): Drop frequency. (cgraph_edge::frequency): New function. * cgraphbuild.c (pass_build_cgraph_edges::execute): Donot pass frequencies. (cgraph_edge::rebuild_edges): Likewise. * cgraphclones.c (cgraph_edge::clone): Scale only counts. (duplicate_thunk_for_node): Do not pass frequency. (cgraph_node::create_clone): Scale only counts. (cgraph_node::create_virtual_clone): Do not pass frequency. (cgraph_node::create_edge_including_clones): Do not pass frequency. (cgraph_node::create_version_clone): Do not pass frequency. * cgraphunit.c (cgraph_node::analyze): Do not pass frequency. (cgraph_node::expand_thunk): Do not pass frequency. (cgraph_node::create_wrapper): Do not pass frequency. * gimple-iterator.c (update_call_edge_frequencies): Do not pass frequency. * gimple-streamer-in.c (input_bb): Scale only IPA counts. * ipa-chkp.c (chkp_produce_thunks): Do not pass frequency. * ipa-cp.c (ipcp_lattice::print): Use frequency function. (gather_caller_stats): Use frequency function. (ipcp_cloning_candidate_p): Use frequency function. (ipcp_propagate_stage): Use frequency function. (get_info_about_necessary_edges): Use frequency function. (update_profiling_info): Update only IPA profile. (update_specialized_profile): Use frequency functoin. (perhaps_add_new_callers): Update only IPA profile. * ipa-devirt.c (ipa_devirt): Use IPA profile. * ipa-fnsummary.c (redirect_to_unreachable): Do not set frequrency. (dump_ipa_call_summary): Use frequency function. (estimate_edge_size_and_time): Use frequency function. (ipa_merge_fn_summary_after_inlining): Use frequency function. * ipa-inline-analysis.c (do_estimate_edge_time): Use IPA profile. * ipa-inline-transform.c (update_noncloned_frequencies): Rename to .. (update_noncloned_counts): ... ths one; scale counts only. (clone_inlined_nodes): Do not scale frequency. (inline_call): Do not pass frequency. * ipa-inline.c (compute_uninlined_call_time): Use IPA profile. (compute_inlined_call_time): Use IPA profile. (want_inline_small_function_p): Use IPA profile. (want_inline_self_recursive_call_p): Use IPA profile. (edge_badness): Use IPA profile. (lookup_recursive_calls): Use IPA profile. (recursive_inlining): Do not pass frequency. (resolve_noninline_speculation): Do not update frequency. (inline_small_functions): Collect max of IPA profile. (dump_overall_stats): Dump IPA porfile. (dump_inline_stats): Dump IPA porfile. (ipa_inline): Collect IPA stats. * ipa-inline.h (clone_inlined_nodes): Update prototype. * ipa-profile.c (ipa_propagate_frequency_1): Use frequency function. (ipa_propagate_frequency): Use frequency function. (ipa_profile): Cleanup. * ipa-prop.c (ipa_make_edge_direct_to_target): Do not pass frequency * ipa-utils.c (ipa_merge_profiles): Merge all profiles. * lto-cgraph.c (lto_output_edge): Do not stream frequency. (input_node): Do not stream frequency. (input_edge): Do not stream frequency. (merge_profile_summaries): Scale only IPA profiles. * omp-simd-clone.c (simd_clone_adjust): Do not pass frequency. * predict.c (drop_profile): Do not recompute frequency. * trans-mem.c (ipa_tm_insert_irr_call): Do not pass frequency. (ipa_tm_insert_gettmclone_call): Do not pass frequency. * tree-cfg.c (execute_fixup_cfg): Drop profile to global0 if needed. * tree-chkp.c (chkp_copy_bounds_for_assign): Do not pass frequency. * tree-emutls.c (gen_emutls_addr): Do not pass frequency. * tree-inline.c (copy_bb): Do not scale frequency. (expand_call_inline): Do not scale frequency. (tree_function_versioning): Do not scale frequency. * ubsan.c (ubsan_create_edge): Do not pass frequency. lto/ChangeLog: 2017-11-10 Jan Hubicka * lto-partition.c (lto_balanced_map): Use frequency accessor. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254636 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cgraph.c | 149 ++++++++++++++++++++--------------------------------------- 1 file changed, 49 insertions(+), 100 deletions(-) (limited to 'gcc/cgraph.c') diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7c3507c6ece..83e496b4239 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -822,7 +822,7 @@ cgraph_edge::set_call_stmt (gcall *new_stmt, bool update_speculative) cgraph_edge * symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, - gcall *call_stmt, profile_count count, int freq, + gcall *call_stmt, profile_count count, bool indir_unknown_callee) { cgraph_edge *edge; @@ -862,10 +862,7 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, edge->next_callee = NULL; edge->lto_stmt_uid = 0; - edge->count = count.ipa (); - edge->frequency = freq; - gcc_checking_assert (freq >= 0); - gcc_checking_assert (freq <= CGRAPH_FREQ_MAX); + edge->count = count; edge->call_stmt = call_stmt; push_cfun (DECL_STRUCT_FUNCTION (caller->decl)); @@ -907,10 +904,10 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, cgraph_edge * cgraph_node::create_edge (cgraph_node *callee, - gcall *call_stmt, profile_count count, int freq) + gcall *call_stmt, profile_count count) { cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count, - freq, false); + false); initialize_inline_failed (edge); @@ -944,11 +941,11 @@ cgraph_allocate_init_indirect_info (void) cgraph_edge * cgraph_node::create_indirect_edge (gcall *call_stmt, int ecf_flags, - profile_count count, int freq, + profile_count count, bool compute_indirect_info) { cgraph_edge *edge = symtab->create_edge (this, NULL, call_stmt, - count, freq, true); + count, true); tree target; initialize_inline_failed (edge); @@ -1060,8 +1057,7 @@ cgraph_edge::remove (void) Return direct edge created. */ cgraph_edge * -cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count, - int direct_frequency) +cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count) { cgraph_node *n = caller; ipa_ref *ref = NULL; @@ -1071,7 +1067,7 @@ cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count, fprintf (dump_file, "Indirect call -> speculative call %s => %s\n", n->dump_name (), n2->dump_name ()); speculative = true; - e2 = n->create_edge (n2, call_stmt, direct_count, direct_frequency); + e2 = n->create_edge (n2, call_stmt, direct_count); initialize_inline_failed (e2); e2->speculative = true; if (TREE_NOTHROW (n2->decl)) @@ -1081,7 +1077,6 @@ cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count, e2->lto_stmt_uid = lto_stmt_uid; e2->in_polymorphic_cdtor = in_polymorphic_cdtor; count -= e2->count; - frequency -= e2->frequency; symtab->call_edge_duplication_hooks (this, e2); ref = n->create_reference (n2, IPA_REF_ADDR, call_stmt); ref->lto_stmt_uid = lto_stmt_uid; @@ -1198,9 +1193,6 @@ cgraph_edge::resolve_speculation (tree callee_decl) in the functions inlined through it. */ } edge->count += e2->count; - edge->frequency += e2->frequency; - if (edge->frequency > CGRAPH_FREQ_MAX) - edge->frequency = CGRAPH_FREQ_MAX; edge->speculative = false; e2->speculative = false; ref->remove_reference (); @@ -1308,9 +1300,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) /* We are producing the final function body and will throw away the callgraph edges really soon. Reset the counts/frequencies to keep verifier happy in the case of roundoff errors. */ - e->count = gimple_bb (e->call_stmt)->count.ipa (); - e->frequency = compute_call_stmt_bb_frequency - (e->caller->decl, gimple_bb (e->call_stmt)); + e->count = gimple_bb (e->call_stmt)->count; } /* Expand speculation into GIMPLE code. */ else @@ -1329,12 +1319,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) profile_probability prob = e->count.probability_in (e->count + e2->count); - if (prob.initialized_p ()) - ; - else if (e->frequency || e2->frequency) - prob = profile_probability::probability_in_gcov_type - (e->frequency, e->frequency + e2->frequency).guessed (); - else + if (!prob.initialized_p ()) prob = profile_probability::even (); new_stmt = gimple_ic (e->call_stmt, dyn_cast (ref->referred), @@ -1355,24 +1340,11 @@ cgraph_edge::redirect_call_stmt_to_callee (void) gcall *ibndret = chkp_retbnd_call_by_val (iresult); struct cgraph_edge *iedge = e2->caller->cgraph_node::get_edge (ibndret); - struct cgraph_edge *dedge; if (dbndret) - { - dedge = iedge->caller->create_edge (iedge->callee, - dbndret, e->count, - e->frequency); - dedge->frequency = compute_call_stmt_bb_frequency - (dedge->caller->decl, gimple_bb (dedge->call_stmt)); - } - iedge->frequency = compute_call_stmt_bb_frequency - (iedge->caller->decl, gimple_bb (iedge->call_stmt)); + iedge->caller->create_edge (iedge->callee, dbndret, e->count); } - e->frequency = compute_call_stmt_bb_frequency - (e->caller->decl, gimple_bb (e->call_stmt)); - e2->frequency = compute_call_stmt_bb_frequency - (e2->caller->decl, gimple_bb (e2->call_stmt)); e2->speculative = false; ref->speculative = false; ref->stmt = NULL; @@ -1610,7 +1582,6 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, cgraph_edge *e = node->get_edge (old_stmt); cgraph_edge *ne = NULL; profile_count count; - int frequency; if (e) { @@ -1644,8 +1615,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, /* Otherwise remove edge and create new one; we can't simply redirect since function has changed, so inline plan and other information attached to edge is invalid. */ - count = e->count.ipa (); - frequency = e->frequency; + count = e->count; if (e->indirect_unknown_callee || e->inline_failed) e->remove (); else @@ -1655,16 +1625,13 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, { /* We are seeing new direct call; compute profile info based on BB. */ basic_block bb = gimple_bb (new_stmt); - count = bb->count.ipa (); - frequency = compute_call_stmt_bb_frequency (current_function_decl, - bb); + count = bb->count; } if (new_call) { ne = node->create_edge (cgraph_node::get_create (new_call), - as_a (new_stmt), count, - frequency); + as_a (new_stmt), count); gcc_assert (ne->inline_failed); } } @@ -2056,10 +2023,9 @@ cgraph_edge::dump_edge_flags (FILE *f) { fprintf (f, "("); count.dump (f); - fprintf (f, ")"); + fprintf (f, ","); + fprintf (f, "%.2f per call) ", frequency () / (double)CGRAPH_FREQ_BASE); } - if (frequency) - fprintf (f, "(%.2f per call) ", frequency / (double)CGRAPH_FREQ_BASE); if (can_throw_external) fprintf (f, "(can throw external) "); } @@ -2205,7 +2171,7 @@ cgraph_node::dump (FILE *f) } fprintf (f, "\n"); - if (count.initialized_p ()) + if (count.ipa ().initialized_p ()) { bool ok = true; bool min = false; @@ -2213,14 +2179,14 @@ cgraph_node::dump (FILE *f) FOR_EACH_ALIAS (this, ref) if (dyn_cast (ref->referring)->count.initialized_p ()) - sum += dyn_cast (ref->referring)->count; + sum += dyn_cast (ref->referring)->count.ipa (); if (global.inlined_to || (symtab->state < EXPANSION && ultimate_alias_target () == this && only_called_directly_p ())) ok = !count.differs_from_p (sum); - else if (count > profile_count::from_gcov_type (100) - && count < sum.apply_scale (99, 100)) + else if (count.ipa () > profile_count::from_gcov_type (100) + && count.ipa () < sum.apply_scale (99, 100)) ok = false, min = true; if (!ok) { @@ -2826,7 +2792,7 @@ cgraph_edge::cannot_lead_to_return_p (void) bool cgraph_edge::maybe_hot_p (void) { - if (!maybe_hot_count_p (NULL, count)) + if (!maybe_hot_count_p (NULL, count.ipa ())) return false; if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED || (callee @@ -2845,12 +2811,12 @@ cgraph_edge::maybe_hot_p (void) if (symtab->state < IPA_SSA) return true; if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE - && frequency < CGRAPH_FREQ_BASE * 3 / 2) + && frequency () < CGRAPH_FREQ_BASE * 3 / 2) return false; if (opt_for_fn (caller->decl, flag_guess_branch_prob)) { if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0 - || frequency <= (CGRAPH_FREQ_BASE + || frequency () <= (CGRAPH_FREQ_BASE / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))) return false; } @@ -3079,7 +3045,7 @@ clone_of_p (cgraph_node *node, cgraph_node *node2) /* Verify edge count and frequency. */ bool -cgraph_edge::verify_count_and_frequency () +cgraph_edge::verify_count () { bool error_found = false; if (!count.verify ()) @@ -3087,21 +3053,6 @@ cgraph_edge::verify_count_and_frequency () error ("caller edge count invalid"); error_found = true; } - if (count.initialized_p () && !(count.ipa () == count)) - { - error ("caller edge count is local"); - error_found = true; - } - if (frequency < 0) - { - error ("caller edge frequency is negative"); - error_found = true; - } - if (frequency > CGRAPH_FREQ_MAX) - { - error ("caller edge frequency is too large"); - error_found = true; - } return error_found; } @@ -3193,11 +3144,6 @@ cgraph_node::verify_node (void) error ("cgraph count invalid"); error_found = true; } - if (count.initialized_p () && !(count.ipa () == count)) - { - error ("cgraph count is local"); - error_found = true; - } if (global.inlined_to && same_comdat_group) { error ("inline clone in same comdat group list"); @@ -3244,7 +3190,7 @@ cgraph_node::verify_node (void) bool check_comdat = comdat_local_p (); for (e = callers; e; e = e->next_caller) { - if (e->verify_count_and_frequency ()) + if (e->verify_count ()) error_found = true; if (check_comdat && !in_same_comdat_group_p (e->caller)) @@ -3277,46 +3223,49 @@ cgraph_node::verify_node (void) } for (e = callees; e; e = e->next_callee) { - if (e->verify_count_and_frequency ()) + if (e->verify_count ()) error_found = true; - /* FIXME: re-enable once cgraph is converted to counts. */ if (gimple_has_body_p (e->caller->decl) - && 0 && !e->caller->global.inlined_to && !e->speculative /* Optimized out calls are redirected to __builtin_unreachable. */ - && (e->frequency + && (e->count.nonzero_p () || ! e->callee->decl || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE) - && (e->frequency - != compute_call_stmt_bb_frequency (e->caller->decl, - gimple_bb (e->call_stmt)))) + && count + == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count + && (!e->count.ipa_p () + && e->count.differs_from_p (gimple_bb (e->call_stmt)->count))) { - error ("caller edge frequency %i does not match BB frequency %i", - e->frequency, - compute_call_stmt_bb_frequency (e->caller->decl, - gimple_bb (e->call_stmt))); + error ("caller edge count does not match BB count"); + fprintf (stderr, "edge count: "); + e->count.dump (stderr); + fprintf (stderr, "\n bb count: "); + gimple_bb (e->call_stmt)->count.dump (stderr); + fprintf (stderr, "\n"); error_found = true; } } for (e = indirect_calls; e; e = e->next_callee) { - if (e->verify_count_and_frequency ()) + if (e->verify_count ()) error_found = true; - /* FIXME: re-enable once cgraph is converted to counts. */ if (gimple_has_body_p (e->caller->decl) && !e->caller->global.inlined_to && !e->speculative - && 0 - && (e->frequency - != compute_call_stmt_bb_frequency (e->caller->decl, - gimple_bb (e->call_stmt)))) + && e->count.ipa_p () + && count + == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count + && (!e->count.ipa_p () + && e->count.differs_from_p (gimple_bb (e->call_stmt)->count))) { - error ("indirect call frequency %i does not match BB frequency %i", - e->frequency, - compute_call_stmt_bb_frequency (e->caller->decl, - gimple_bb (e->call_stmt))); + error ("indirect call count does not match BB count"); + fprintf (stderr, "edge count: "); + e->count.dump (stderr); + fprintf (stderr, "\n bb count: "); + gimple_bb (e->call_stmt)->count.dump (stderr); + fprintf (stderr, "\n"); error_found = true; } } -- cgit v1.2.1 From 7c3432355e5a6fbd32ce0ddcca76ba21d5343f6d Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 13 Nov 2017 17:23:25 +0000 Subject: * cgraph.c (cgraph_edge::sreal_frequency): New function. * cgraph.h (cgraph_edge::sreal_frequency): Declare. * ipa-fnsummary.c (dump_ipa_call_summary): Use sreal_frequency. (estimate_edge_size_and_time): Likewise. (ipa_merge_fn_summary_after_inlining): Likewise. * ipa-inline.c (cgraph_freq_base_rec): Remove. (compute_uninlined_call_time): Use sreal_frequency. (compute_inlined_call_time): Likewise. (ipa_inline): Do not initialize cgraph_freq_base_rec. * profile-count.c: Include sreal.h. (profile_count::to_sreal_scale): New. * profile-count.h: Forward declare sreal. (profile_count::to_sreal_scale): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254696 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cgraph.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gcc/cgraph.c') diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 83e496b4239..bc60fc90f56 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -3880,4 +3880,16 @@ cgraph_node::has_thunk_p (cgraph_node *node, void *) return false; } +/* Expected frequency of executions within the function. + When set to CGRAPH_FREQ_BASE, the edge is expected to be called once + per function call. The range is 0 to CGRAPH_FREQ_MAX. */ + +sreal +cgraph_edge::sreal_frequency () +{ + return count.to_sreal_scale (caller->global.inlined_to + ? caller->global.inlined_to->count + : caller->count); +} + #include "gt-cgraph.h" -- cgit v1.2.1