From 95d34a2e597de042b3a3fe61fd4d5238c5529f1c Mon Sep 17 00:00:00 2001 From: Easwaran Raman Date: Thu, 22 Feb 2018 19:44:08 +0000 Subject: [PATCH] [ThinLTO] Represent relative BF using a scaled representation . Summary: The current integer representation of relative block frequency prevents representing relative block frequencies below 1. This change uses a 8 of the 29 bits to represent the decimal part by using a fixed scale of -8. Reviewers: tejohnson, davidxl Subscribers: mehdi_amini, inglorion, llvm-commits Differential Revision: https://reviews.llvm.org/D43520 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325823 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/ModuleSummaryIndex.h | 23 +++++++++++++++---- lib/Analysis/ModuleSummaryAnalysis.cpp | 14 +++-------- ...hinlto-function-summary-callgraph-relbf.ll | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 497e0d6d8b0..5db49af45b4 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/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 #include #include @@ -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(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; + Scaled64 Temp(BlockFreq, ScaleShift); + Temp /= Scaled64::get(EntryFreq); + + uint64_t Sum = + SaturatingAdd(Temp.toInt(), RelBlockFreq); Sum = std::min(Sum, uint64_t(MaxRelBlockFreq)); RelBlockFreq = static_cast(Sum); } diff --git a/lib/Analysis/ModuleSummaryAnalysis.cpp b/lib/Analysis/ModuleSummaryAnalysis.cpp index 9293f603479..4a84816f616 100644 --- a/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -279,17 +279,9 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, // Add the relative block frequency to CalleeInfo if there is no profile // information. if (BFI != nullptr && Hotness == CalleeInfo::HotnessType::Unknown) { - auto BBFreq = BFI->getBlockFreq(&BB).getFrequency(); - // FIXME: This might need some scaling to prevent BBFreq values from - // being rounded down to 0. - auto EntryFreq = BFI->getEntryFreq(); - // Block frequencies can be directly set for a block and so we need to - // handle the case of entry frequency being 0. - if (EntryFreq) - BBFreq /= EntryFreq; - else - BBFreq = 0; - ValueInfo.updateRelBlockFreq(BBFreq); + uint64_t BBFreq = BFI->getBlockFreq(&BB).getFrequency(); + uint64_t EntryFreq = BFI->getEntryFreq(); + ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq); } } else { // Skip inline assembly calls. diff --git a/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll b/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll index 779acada520..9955de6d958 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll @@ -11,7 +11,7 @@ ; CHECK: ; CHECK: