aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-08-13 14:21:16 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-08-13 12:21:16 +0000
commit09ce36608d268b1a3124411a3ad2f701e5cf24ec (patch)
treee903dc537f27c5dd690cb3a98029321225e8f7b4 /gcc/ipa.c
parent537e035c48955b3ea88dcb3a4b0ff03ef4bb2e31 (diff)
downloadgcc-09ce36608d268b1a3124411a3ad2f701e5cf24ec.zip
gcc-09ce36608d268b1a3124411a3ad2f701e5cf24ec.tar.gz
gcc-09ce36608d268b1a3124411a3ad2f701e5cf24ec.tar.bz2
cgraph.c (cgraph_turn_edge_to_speculative): Return newly introduced edge; fix typo in sanity check.
* cgraph.c (cgraph_turn_edge_to_speculative): Return newly introduced edge; fix typo in sanity check. (cgraph_resolve_speculation): Export; improve diagnostic. (cgraph_redirect_edge_call_stmt_to_callee): Better diagnostic; cancel speculation at type mismatch. * cgraph.h (cgraph_turn_edge_to_speculative): Update. (cgraph_resolve_speculation): Declare. (symtab_can_be_discarded): New function. * value-prof.c (gimple_ic_transform): Remove actual transform code. * ipa-inline-transform.c (speculation_removed): New global var. (clone_inlined_nodes): See if speculation can be removed. (inline_call): If speculations was removed, we growths may not match. * ipa-inline.c (can_inline_edge_p): Add DISREGARD_LIMITS parameter. (speculation_useful_p): New function. (resolve_noninline_speculation): New function. (inline_small_functions): Resolve useless speculations. * ipa-inline.h (speculation_useful_p): Declare * ipa.c (can_replace_by_local_alias): Simplify. (ipa_profile): Produce speculative calls in non-lto, too; add simple cost model; produce local aliases. From-SVN: r201683
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c156
1 files changed, 104 insertions, 52 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index c870a6f..1578aed 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -768,11 +768,7 @@ bool
can_replace_by_local_alias (symtab_node node)
{
return (symtab_node_availability (node) > AVAIL_OVERWRITABLE
- && !DECL_EXTERNAL (node->symbol.decl)
- && (!DECL_ONE_ONLY (node->symbol.decl)
- || node->symbol.resolution == LDPR_PREVAILING_DEF
- || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
- || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP));
+ && !symtab_can_be_discarded (node));
}
/* Mark visibility of all functions.
@@ -1407,53 +1403,9 @@ ipa_profile (void)
bool something_changed = false;
int i;
gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
-
- /* Produce speculative calls: we saved common traget from porfiling into
- e->common_target_id. Now, at link time, we can look up corresponding
- function node and produce speculative call. */
- if (in_lto_p)
- {
- struct cgraph_edge *e;
- struct cgraph_node *n,*n2;
-
- init_node_map (false);
- FOR_EACH_DEFINED_FUNCTION (n)
- {
- bool update = false;
-
- for (e = n->indirect_calls; e; e = e->next_callee)
- if (e->indirect_info->common_target_id)
- {
- n2 = find_func_by_profile_id (e->indirect_info->common_target_id);
- if (n2)
- {
- if (dump_file)
- {
- fprintf (dump_file, "Indirect call -> direct call from"
- " other module %s/%i => %s/%i, prob %3.2f\n",
- xstrdup (cgraph_node_name (n)), n->symbol.order,
- xstrdup (cgraph_node_name (n2)), n2->symbol.order,
- e->indirect_info->common_target_probability
- / (float)REG_BR_PROB_BASE);
- }
- cgraph_turn_edge_to_speculative
- (e, n2,
- apply_scale (e->count,
- e->indirect_info->common_target_probability),
- apply_scale (e->frequency,
- e->indirect_info->common_target_probability));
- update = true;
- }
- else
- if (dump_file)
- fprintf (dump_file, "Function with profile-id %i not found.\n",
- e->indirect_info->common_target_id);
- }
- if (update)
- inline_update_overall_summary (n);
- }
- del_node_map ();
- }
+ struct cgraph_node *n,*n2;
+ int nindirect = 0, ncommon = 0, nunknown = 0, nuseless = 0, nconverted = 0;
+ bool node_map_initialized = false;
if (dump_file)
dump_histogram (dump_file, histogram);
@@ -1523,6 +1475,106 @@ ipa_profile (void)
histogram.release();
free_alloc_pool (histogram_pool);
+ /* Produce speculative calls: we saved common traget from porfiling into
+ e->common_target_id. Now, at link time, we can look up corresponding
+ function node and produce speculative call. */
+
+ FOR_EACH_DEFINED_FUNCTION (n)
+ {
+ bool update = false;
+
+ for (e = n->indirect_calls; e; e = e->next_callee)
+ {
+ if (n->count)
+ nindirect++;
+ if (e->indirect_info->common_target_id)
+ {
+ if (!node_map_initialized)
+ init_node_map (false);
+ node_map_initialized = true;
+ ncommon++;
+ n2 = find_func_by_profile_id (e->indirect_info->common_target_id);
+ if (n2)
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Indirect call -> direct call from"
+ " other module %s/%i => %s/%i, prob %3.2f\n",
+ xstrdup (cgraph_node_name (n)), n->symbol.order,
+ xstrdup (cgraph_node_name (n2)), n2->symbol.order,
+ e->indirect_info->common_target_probability
+ / (float)REG_BR_PROB_BASE);
+ }
+ if (e->indirect_info->common_target_probability
+ < REG_BR_PROB_BASE / 2)
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: probability is too low.\n");
+ }
+ else if (!cgraph_maybe_hot_edge_p (e))
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: call is cold.\n");
+ }
+ else if (cgraph_function_body_availability (n2)
+ <= AVAIL_OVERWRITABLE
+ && symtab_can_be_discarded ((symtab_node) n2))
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: target is overwritable "
+ "and can be discarded.\n");
+ }
+ else
+ {
+ /* Target may be overwritable, but profile says that
+ control flow goes to this particular implementation
+ of N2. Speculate on the local alias to allow inlining.
+ */
+ if (!symtab_can_be_discarded ((symtab_node) n2))
+ n2 = cgraph (symtab_nonoverwritable_alias ((symtab_node)n2));
+ nconverted++;
+ cgraph_turn_edge_to_speculative
+ (e, n2,
+ apply_scale (e->count,
+ e->indirect_info->common_target_probability),
+ apply_scale (e->frequency,
+ e->indirect_info->common_target_probability));
+ update = true;
+ }
+ }
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function with profile-id %i not found.\n",
+ e->indirect_info->common_target_id);
+ nunknown++;
+ }
+ }
+ }
+ if (update)
+ inline_update_overall_summary (n);
+ }
+ if (node_map_initialized)
+ del_node_map ();
+ if (dump_file && nindirect)
+ fprintf (dump_file,
+ "%i indirect calls trained.\n"
+ "%i (%3.2f%%) have common target.\n"
+ "%i (%3.2f%%) targets was not found.\n"
+ "%i (%3.2f%%) speculations seems useless.\n"
+ "%i (%3.2f%%) speculations produced.\n",
+ nindirect,
+ ncommon, ncommon * 100.0 / nindirect,
+ nunknown, nunknown * 100.0 / nindirect,
+ nuseless, nuseless * 100.0 / nindirect,
+ nconverted, nconverted * 100.0 / nindirect);
+
order_pos = ipa_reverse_postorder (order);
for (i = order_pos - 1; i >= 0; i--)
{