diff options
Diffstat (limited to 'gcc/profile-count.cc')
-rw-r--r-- | gcc/profile-count.cc | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc index 190bbeb..8f05a79 100644 --- a/gcc/profile-count.cc +++ b/gcc/profile-count.cc @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "wide-int.h" #include "sreal.h" +#include "profile.h" /* Names from profile_quality enum values. */ @@ -557,7 +558,7 @@ profile_count::operator* (const sreal &num) const sreal scaled = num * m_val; gcc_checking_assert (scaled >= 0); profile_count ret; - if (m_val > max_count) + if (scaled > max_count) ret.m_val = max_count; else ret.m_val = scaled.to_nearest_int (); @@ -570,3 +571,27 @@ profile_count::operator*= (const sreal &num) { return *this * num; } + +/* Make counter forcibly nonzero. */ +profile_count +profile_count::force_nonzero () const +{ + if (!initialized_p ()) + return *this; + profile_count ret = *this; + /* Generally values are forced non-zero to handle inconsistent profile + where count 0 needs to be scaled up to non-zero. + + Use cutoff value here to avoid situation where profile has large + cutoff and we perform count = count * num / den where num is non-zero + and den is 0. If profile was scaled by large factor, forcing value + to 1 would lead to large scale factor. */ + gcov_unsigned_t small = profile_info ? profile_info->cutoff / 2 + 1 + : 1; + if (ret.m_val < small) + { + ret.m_val = small; + ret.m_quality = MIN (m_quality, ADJUSTED); + } + return ret; +} |