to = e->caller;
if (to->inlined_to)
to = to->inlined_to;
+
+ /* In case callee has AFDO profile but caller has GLOBAL0 we need
+ to re-scale it so it can have non-zero AFDO profile. */
+ if (callee->count.quality () == AFDO
+ && e->count.nonzero_p ()
+ && (to->count.quality () == GUESSED_GLOBAL0_AFDO
+ || to->count.quality () == GUESSED_GLOBAL0_ADJUSTED))
+ {
+ profile_count num = callee->count;
+ profile_count den = e->count;
+ profile_count::adjust_for_ipa_scaling (&num, &den);
+ if (dump_file)
+ {
+ fprintf (dump_file, "Rescalling profile of caller %s "
+ "to allow non-zero AFDO counts:",
+ to->dump_name ());
+ den.dump (dump_file);
+ fprintf (dump_file, " -> ");
+ num.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ to->apply_scale (num, den);
+ to->frequency = std::max (to->frequency, callee->frequency);
+ /* Do not update original, so possible additional calls of callee
+ are handled reasonably well. */
+ update_original = false;
+ gcc_checking_assert (to->count.quality () == AFDO);
+ if (dump_file)
+ {
+ fprintf (dump_file, "Scaled profile of %s: ", to->dump_name ());
+ to->count.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ }
if (to->thunk)
{
struct cgraph_node *target = to->callees->callee;
/* Be sure that ret is not local if num is global.
Also ensure that ret is not global0 when num is global. */
if (num.ipa_p ())
- ret.m_quality = MAX (ret.m_quality,
- num == num.ipa () ? GUESSED : num.m_quality);
+ {
+ /* This is common case of AFDO scaling when we upgrade
+ GLOBAL0_AFDO function to AFDO. Be sure that result
+ is AFDO and not GUESSED (which is unnecesarily low). */
+ if (num.m_quality == AFDO
+ && (ret.m_quality != GUESSED
+ && ret.m_quality != GUESSED_LOCAL))
+ ret.m_quality = AFDO;
+ else
+ ret.m_quality = MAX (ret.m_quality,
+ num == num.ipa () ? GUESSED : num.m_quality);
+ }
return ret;
}