diff options
Diffstat (limited to 'gcc/profile-count.c')
-rw-r--r-- | gcc/profile-count.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/gcc/profile-count.c b/gcc/profile-count.c index d7031404645..51c3b74fefa 100644 --- a/gcc/profile-count.c +++ b/gcc/profile-count.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "data-streamer.h" #include "cgraph.h" #include "wide-int.h" +#include "sreal.h" /* Dump THIS to F. */ @@ -255,3 +256,55 @@ profile_count::to_cgraph_frequency (profile_count entry_bb_count) const return CGRAPH_FREQ_MAX; return MIN (scale, CGRAPH_FREQ_MAX); } + +/* Return THIS/IN as sreal value. */ + +sreal +profile_count::to_sreal_scale (profile_count in, bool *known) const +{ + if (!initialized_p ()) + { + if (known) + *known = false; + return CGRAPH_FREQ_BASE; + } + if (known) + *known = true; + if (*this == profile_count::zero ()) + return 0; + gcc_checking_assert (in.initialized_p ()); + + if (!in.m_val) + { + if (!m_val) + return 1; + return m_val * 4; + } + return (sreal)m_val / (sreal)in.m_val; +} + +/* We want to scale profile across function boundary from NUM to DEN. + Take care of the side case when DEN is zeros. We still want to behave + sanely here which means + - scale to profile_count::zero () if NUM is profile_count::zero + - do not affect anything if NUM == DEN + - preserve counter value but adjust quality in other cases. */ + +void +profile_count::adjust_for_ipa_scaling (profile_count *num, + profile_count *den) +{ + /* Scaling is no-op if NUM and DEN are the same. */ + if (*num == *den) + return; + /* Scaling to zero is always zeor. */ + if (*num == profile_count::zero ()) + return; + /* If den is non-zero we are safe. */ + if (den->force_nonzero () == *den) + return; + /* Force both to non-zero so we do not push profiles to 0 when + both num == 0 and den == 0. */ + *den = den->force_nonzero (); + *num = num->force_nonzero (); +} |