aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-utils.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/ipa-utils.c
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517 Author: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed Jun 17 00:16:36 2020 +0000 Daily bump.
Diffstat (limited to 'gcc/ipa-utils.c')
-rw-r--r--gcc/ipa-utils.c180
1 files changed, 60 insertions, 120 deletions
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 2e82980..23e7f71 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -674,136 +674,75 @@ ipa_merge_profiles (struct cgraph_node *dst,
for (e = dst->indirect_calls, e2 = src->indirect_calls; e;
e2 = (e2 ? e2->next_callee : NULL), e = e->next_callee)
{
- profile_count count = gimple_bb (e->call_stmt)->count;
- if (copy_counts)
+ if (!e->speculative && !e2->speculative)
{
- e->indirect_info->common_target_id
- = e2->indirect_info->common_target_id;
- e->indirect_info->common_target_probability
- = e2->indirect_info->common_target_probability;
- }
- else if (e->indirect_info->common_target_id
- || e2->indirect_info->common_target_id)
- {
- sreal scale1
- = e->count.ipa().to_sreal_scale (count);
- sreal scale2
- = e2->count.ipa().to_sreal_scale (count);
-
- if (scale1 == 0 && scale2 == 0)
- scale1 = scale2 = 1;
- sreal sum = scale1 + scale2;
- int scaled_probability1
- = ((sreal)e->indirect_info->common_target_probability
- * scale1 / sum).to_int ();
- int scaled_probability2
- = ((sreal)e2->indirect_info->common_target_probability
- * scale2 / sum).to_int ();
- if (symtab->dump_file)
- {
- fprintf (symtab->dump_file,
- "Merging common targets %i prob %i"
- " and %i prob %i with scales %f %f\n",
- e->indirect_info->common_target_id,
- e->indirect_info->common_target_probability,
- e2->indirect_info->common_target_id,
- e2->indirect_info->common_target_probability,
- scale1.to_double (),
- scale2.to_double ());
- fprintf (symtab->dump_file, "Combined BB count ");
- count.dump (symtab->dump_file);
- fprintf (symtab->dump_file, " dst edge count ");
- e->count.dump (symtab->dump_file);
- fprintf (symtab->dump_file, " src edge count ");
- e2->count.dump (symtab->dump_file);
- fprintf (symtab->dump_file, "\n");
- }
- if (e->indirect_info->common_target_id
- == e2->indirect_info->common_target_id)
- e->indirect_info->common_target_probability
- = scaled_probability1 + scaled_probability2;
- else if (!e2->indirect_info->common_target_id
- || scaled_probability1 > scaled_probability2)
- e->indirect_info->common_target_probability
- = scaled_probability1;
- else
- {
- e->indirect_info->common_target_id
- = e2->indirect_info->common_target_id;
- e->indirect_info->common_target_probability
- = scaled_probability2;
- }
- if (symtab->dump_file)
- fprintf (symtab->dump_file, "Merged as %i prob %i\n",
- e->indirect_info->common_target_id,
- e->indirect_info->common_target_probability);
+ /* FIXME: we need to also merge ipa-profile histograms
+ because with LTO merging happens from lto-symtab before
+ these are converted to indirect edges. */
+ e->count = gimple_bb (e->call_stmt)->count;
+ continue;
}
- /* When call is speculative, we need to re-distribute probabilities
- the same way as they was. This is not really correct because
- in the other copy the speculation may differ; but probably it
- is not really worth the effort. */
- if (e->speculative)
+ /* When copying just remove all speuclations on dst and then copy
+ one from src. */
+ if (copy_counts)
{
- cgraph_edge *direct, *indirect;
- cgraph_edge *direct2 = NULL, *indirect2 = NULL;
- ipa_ref *ref;
-
- e->speculative_call_info (direct, indirect, ref);
- gcc_assert (e == indirect);
- if (e2 && e2->speculative)
- e2->speculative_call_info (direct2, indirect2, ref);
- if (indirect->count > profile_count::zero ()
- || direct->count > profile_count::zero ())
+ while (e->speculative)
+ cgraph_edge::resolve_speculation (e, NULL);
+ e->count = gimple_bb (e->call_stmt)->count;
+ if (e2->speculative)
{
- /* We should mismatch earlier if there is no matching
- indirect edge. */
- if (!e2)
- {
- if (symtab->dump_file)
- fprintf (symtab->dump_file,
- "Mismatch in merging indirect edges\n");
- }
- else if (!e2->speculative)
- indirect->count += e2->count;
- else if (e2->speculative)
+ for (cgraph_edge *e3 = e2->first_speculative_call_target ();
+ e3;
+ e3 = e3->next_speculative_call_target ())
{
- if (DECL_ASSEMBLER_NAME (direct2->callee->decl)
- != DECL_ASSEMBLER_NAME (direct->callee->decl))
- {
- if (direct2->count >= direct->count)
- {
- direct->redirect_callee (direct2->callee);
- indirect->count += indirect2->count
- + direct->count;
- direct->count = direct2->count;
- }
- else
- indirect->count += indirect2->count + direct2->count;
- }
- else
- {
- direct->count += direct2->count;
- indirect->count += indirect2->count;
- }
+ cgraph_edge *ns;
+ ns = e->make_speculative
+ (dyn_cast <cgraph_node *>
+ (e3->speculative_call_target_ref ()->referred),
+ e3->count, e3->speculative_id);
+ /* Target may differ from ref (for example it may be
+ redirected to local alias. */
+ ns->redirect_callee (e3->callee);
}
}
- else
- /* At the moment we should have only profile feedback based
- speculations when merging. */
- gcc_unreachable ();
+ continue;
}
- else if (e2 && e2->speculative)
- {
- cgraph_edge *direct, *indirect;
- ipa_ref *ref;
- e2->speculative_call_info (direct, indirect, ref);
- e->count = count;
- e->make_speculative (direct->callee, direct->count);
+ /* Iterate all speculations in SRC, see if corresponding ones exist
+ int DST and if so, sum the counts. Otherwise create new
+ speculation. */
+ int max_spec = 0;
+ for (cgraph_edge *e3 = e->first_speculative_call_target ();
+ e3;
+ e3 = e3->next_speculative_call_target ())
+ if (e3->speculative_id > max_spec)
+ max_spec = e3->speculative_id;
+ for (cgraph_edge *e3 = e2->first_speculative_call_target ();
+ e3;
+ e3 = e3->next_speculative_call_target ())
+ {
+ cgraph_edge *te
+ = e->speculative_call_for_target
+ (dyn_cast <cgraph_node *>
+ (e3->speculative_call_target_ref ()->referred));
+ if (te)
+ te->count = te->count + e3->count;
+ else
+ {
+ e->count = e->count + e3->count;
+ cgraph_edge *ns;
+ ns = e->make_speculative
+ (dyn_cast <cgraph_node *>
+ (e3->speculative_call_target_ref ()
+ ->referred),
+ e3->count,
+ e3->speculative_id + max_spec + 1);
+ /* Target may differ from ref (for example it may be
+ redirected to local alias. */
+ ns->redirect_callee (e3->callee);
+ }
}
- else
- e->count = count;
}
if (!preserve_body)
src->release_body ();
@@ -817,7 +756,8 @@ ipa_merge_profiles (struct cgraph_node *dst,
src->decl = oldsrcdecl;
}
-/* Return true if call to DEST is known to be self-recusive call withing FUNC. */
+/* Return true if call to DEST is known to be self-recusive
+ call withing FUNC. */
bool
recursive_call_p (tree func, tree dest)