diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/IR/ModuleSummaryIndex.h | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h index 497e0d6d8b0..5db49af45b4 100644 --- a/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h @@ -26,6 +26,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Module.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/ScaledNumber.h" #include <algorithm> #include <array> #include <cassert> @@ -59,7 +60,11 @@ struct CalleeInfo { // The size of the bit-field might need to be adjusted if more values are // added to HotnessType enum. uint32_t Hotness : 3; + + /// The value stored in RelBlockFreq has to be interpreted as the digits of + /// a scaled number with a scale of \p -ScaleShift. uint32_t RelBlockFreq : 29; + static constexpr int32_t ScaleShift = 8; static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1; CalleeInfo() @@ -73,10 +78,20 @@ struct CalleeInfo { HotnessType getHotness() const { return HotnessType(Hotness); } - // When there are multiple edges between the same (caller, callee) pair, the - // relative block frequencies are summed up. - void updateRelBlockFreq(uint64_t RBF) { - uint64_t Sum = SaturatingAdd<uint64_t>(RelBlockFreq, RBF); + /// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq + /// + /// BlockFreq is divided by EntryFreq and added to RelBlockFreq. To represent + /// fractional values, the result is represented as a fixed point number with + /// scale of -ScaleShift. + void updateRelBlockFreq(uint64_t BlockFreq, uint64_t EntryFreq) { + if (EntryFreq == 0) + return; + using Scaled64 = ScaledNumber<uint64_t>; + Scaled64 Temp(BlockFreq, ScaleShift); + Temp /= Scaled64::get(EntryFreq); + + uint64_t Sum = + SaturatingAdd<uint64_t>(Temp.toInt<uint64_t>(), RelBlockFreq); Sum = std::min(Sum, uint64_t(MaxRelBlockFreq)); RelBlockFreq = static_cast<uint32_t>(Sum); } |