diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-11-20 16:02:55 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@linaro.org> | 2017-11-20 16:02:55 +0000 |
commit | d58952aefb03632bbb5b441d5c0bd330711f0af1 (patch) | |
tree | d046e56bfbd6a40106ae6ab96fafc954f1dfc955 /gcc/cgraph.c | |
parent | 648f8fc59b2cc39abd24f4c22388b346cdebcc31 (diff) | |
parent | 50221fae802a10fafe95e61d40504a58da33e98f (diff) | |
download | gcc-linaro-dev/sve.tar.gz |
Merge trunk into svelinaro-dev/sve
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 161 |
1 files changed, 61 insertions, 100 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7c3507c6ece..bc60fc90f56 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<cgraph_node *> (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 <gcall *> (new_stmt), count, - frequency); + as_a <gcall *> (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 <cgraph_node *> (ref->referring)->count.initialized_p ()) - sum += dyn_cast <cgraph_node *> (ref->referring)->count; + sum += dyn_cast <cgraph_node *> (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; } } @@ -3931,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" |