Fix merging of common traget info.

* ipa-utils.c (ipa_merge_profiles): Improve dumping; merge common
	targets.

From-SVN: r279373
This commit is contained in:
Jan Hubicka 2019-12-13 16:41:55 +01:00 committed by Jan Hubicka
parent 3d66c77719
commit e44deb433b
2 changed files with 156 additions and 38 deletions

View file

@ -1,3 +1,8 @@
2019-12-13 Jan Hubicka <hubicka@ucw.cz>
* ipa-utils.c (ipa_merge_profiles): Improve dumping; merge common
targets.
2019-12-13 Andrew Stubbs <ams@codesourcery.com>
* config/gcn/gcn-valu.md (sdwa): New mode attribute.

View file

@ -423,11 +423,6 @@ ipa_merge_profiles (struct cgraph_node *dst,
if (!src->count.initialized_p ()
|| !(src->count.ipa () == src->count))
return;
if (symtab->dump_file)
{
fprintf (symtab->dump_file, "Merging profiles of %s to %s\n",
src->dump_name (), dst->dump_name ());
}
profile_count orig_count = dst->count;
/* Either sum the profiles if both are IPA and not global0, or
@ -451,6 +446,19 @@ ipa_merge_profiles (struct cgraph_node *dst,
if (dst->count == orig_count)
return;
if (symtab->dump_file)
{
fprintf (symtab->dump_file, "Merging profiles of %s count:",
src->dump_name ());
src->count.dump (symtab->dump_file);
fprintf (symtab->dump_file, " to %s count:",
dst->dump_name ());
orig_count.dump (symtab->dump_file);
fprintf (symtab->dump_file, " resulting count:");
dst->count.dump (symtab->dump_file);
fprintf (symtab->dump_file, "\n");
}
/* First handle functions with no gimple body. */
if (dst->thunk.thunk_p || dst->alias
|| src->thunk.thunk_p || src->alias)
@ -516,45 +524,86 @@ ipa_merge_profiles (struct cgraph_node *dst,
else
{
basic_block srcbb, dstbb;
struct cgraph_edge *e, *e2;
FOR_ALL_BB_FN (srcbb, srccfun)
for (e = dst->callees, e2 = src->callees; e && e2 && match;
e2 = e2->next_callee, e = e->next_callee)
{
unsigned int i;
dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index);
if (dstbb == NULL)
if (gimple_bb (e->call_stmt)->index
!= gimple_bb (e2->call_stmt)->index)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"No matching block for bb %i.\n",
srcbb->index);
"Giving up; call stmt mismatch.\n");
match = false;
break;
}
if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs))
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Edge count mismatch for bb %i.\n",
srcbb->index);
match = false;
break;
}
for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
{
edge srce = EDGE_SUCC (srcbb, i);
edge dste = EDGE_SUCC (dstbb, i);
if (srce->dest->index != dste->dest->index)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Succ edge mismatch for bb %i.\n",
srce->dest->index);
match = false;
break;
}
}
}
if (e || e2)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Giving up; number of calls differs.\n");
match = false;
}
for (e = dst->indirect_calls, e2 = src->indirect_calls; e && e2 && match;
e2 = e2->next_callee, e = e->next_callee)
{
if (gimple_bb (e->call_stmt)->index
!= gimple_bb (e2->call_stmt)->index)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Giving up; indirect call stmt mismatch.\n");
match = false;
}
}
if (e || e2)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Giving up; number of indirect calls differs.\n");
match=false;
}
if (match)
FOR_ALL_BB_FN (srcbb, srccfun)
{
unsigned int i;
dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index);
if (dstbb == NULL)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"No matching block for bb %i.\n",
srcbb->index);
match = false;
break;
}
if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs))
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Edge count mismatch for bb %i.\n",
srcbb->index);
match = false;
break;
}
for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
{
edge srce = EDGE_SUCC (srcbb, i);
edge dste = EDGE_SUCC (dstbb, i);
if (srce->dest->index != dste->dest->index)
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Succ edge mismatch for bb %i.\n",
srce->dest->index);
match = false;
break;
}
}
}
}
if (match)
{
@ -626,6 +675,70 @@ ipa_merge_profiles (struct cgraph_node *dst,
e2 = (e2 ? e2->next_callee : NULL), e = e->next_callee)
{
profile_count count = gimple_bb (e->call_stmt)->count;
if (copy_counts)
{
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);
}
/* 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
@ -647,8 +760,8 @@ ipa_merge_profiles (struct cgraph_node *dst,
indirect edge. */
if (!e2)
{
if (dump_file)
fprintf (dump_file,
if (symtab->dump_file)
fprintf (symtab->dump_file,
"Mismatch in merging indirect edges\n");
}
else if (!e2->speculative)