From eb081fd0e2cb852c3cf0ef09da497ed3fee77029 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 28 Nov 2019 15:21:08 +0100 Subject: [PATCH] ipa-utils.c (ipa_merge_profiles): Be sure that all type transtions of counters are done same way. * ipa-utils.c (ipa_merge_profiles): Be sure that all type transtions of counters are done same way. From-SVN: r278809 --- gcc/ChangeLog | 5 ++++ gcc/ipa-utils.c | 64 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9897c0e604e..aecc351e0fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-11-28 Jan Hubicka + + * ipa-utils.c (ipa_merge_profiles): Be sure that all type transtions + of counters are done same way. + 2019-11-28 Jan Hubicka * ipa-cp.c (update_profiling_info): Fix scaling. diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 2830d41026a..fdbecdb7b35 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -398,6 +398,7 @@ ipa_merge_profiles (struct cgraph_node *dst, tree oldsrcdecl = src->decl; struct function *srccfun, *dstcfun; bool match = true; + bool copy_counts = false; if (!src->definition || !dst->definition) @@ -429,10 +430,26 @@ ipa_merge_profiles (struct cgraph_node *dst, } profile_count orig_count = dst->count; - if (dst->count.initialized_p () && dst->count.ipa () == dst->count) - dst->count += src->count.ipa (); - else - dst->count = src->count.ipa (); + /* Either sum the profiles if both are IPA and not global0, or + pick more informative one (that is nonzero IPA if other is + uninitialized, guessed or global0). */ + + if ((dst->count.ipa ().nonzero_p () + || src->count.ipa ().nonzero_p ()) + && dst->count.ipa ().initialized_p () + && src->count.ipa ().initialized_p ()) + dst->count = dst->count.ipa () + src->count.ipa (); + else if (dst->count.ipa ().initialized_p ()) + ; + else if (src->count.ipa ().initialized_p ()) + { + copy_counts = true; + dst->count = src->count.ipa (); + } + + /* If no updating needed return early. */ + if (dst->count == orig_count) + return; /* First handle functions with no gimple body. */ if (dst->thunk.thunk_p || dst->alias @@ -544,6 +561,16 @@ ipa_merge_profiles (struct cgraph_node *dst, struct cgraph_edge *e, *e2; basic_block srcbb, dstbb; + /* Function and global profile may be out of sync. First scale it same + way as fixup_cfg would. */ + profile_count srcnum = src->count; + profile_count srcden = ENTRY_BLOCK_PTR_FOR_FN (srccfun)->count; + bool srcscale = srcnum.initialized_p () && !(srcnum == srcden); + profile_count dstnum = orig_count; + profile_count dstden = ENTRY_BLOCK_PTR_FOR_FN (dstcfun)->count; + bool dstscale = !copy_counts + && dstnum.initialized_p () && !(dstnum == dstden); + /* TODO: merge also statement histograms. */ FOR_ALL_BB_FN (srcbb, srccfun) { @@ -551,15 +578,15 @@ ipa_merge_profiles (struct cgraph_node *dst, dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index); - /* Either sum the profiles if both are IPA and not global0, or - pick more informative one (that is nonzero IPA if other is - uninitialized, guessed or global0). */ - if (!dstbb->count.ipa ().initialized_p () - || (dstbb->count.ipa () == profile_count::zero () - && (srcbb->count.ipa ().initialized_p () - && !(srcbb->count.ipa () == profile_count::zero ())))) + profile_count srccount = srcbb->count; + if (srcscale) + srccount = srccount.apply_scale (srcnum, srcden); + if (dstscale) + dstbb->count = dstbb->count.apply_scale (dstnum, dstden); + + if (copy_counts) { - dstbb->count = srcbb->count; + dstbb->count = srccount; for (i = 0; i < EDGE_COUNT (srcbb->succs); i++) { edge srce = EDGE_SUCC (srcbb, i); @@ -568,18 +595,21 @@ ipa_merge_profiles (struct cgraph_node *dst, dste->probability = srce->probability; } } - else if (srcbb->count.ipa ().initialized_p () - && !(srcbb->count.ipa () == profile_count::zero ())) + else { for (i = 0; i < EDGE_COUNT (srcbb->succs); i++) { edge srce = EDGE_SUCC (srcbb, i); edge dste = EDGE_SUCC (dstbb, i); dste->probability = - dste->probability * dstbb->count.probability_in (dstbb->count + srcbb->count) - + srce->probability * srcbb->count.probability_in (dstbb->count + srcbb->count); + dste->probability * dstbb->count.ipa ().probability_in + (dstbb->count.ipa () + + srccount.ipa ()) + + srce->probability * srcbb->count.ipa ().probability_in + (dstbb->count.ipa () + + srccount.ipa ()); } - dstbb->count += srcbb->count; + dstbb->count = dstbb->count.ipa () + srccount.ipa (); } } push_cfun (dstcfun); -- 2.30.2