mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 06:39:12 +00:00
[PGO] Move profile summary interface/impl into InstrProf.[*] /NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257819 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f881fc9fb9
commit
fc8577b821
@ -27,6 +27,7 @@
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
@ -553,6 +554,68 @@ ValueProfData *
|
||||
serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,
|
||||
ValueProfData *Dst);
|
||||
|
||||
///// Profile summary computation ////
|
||||
// The 'show' command displays richer summary of the profile data. The profile
|
||||
// summary is one or more (Cutoff, MinBlockCount, NumBlocks) triplets. Given a
|
||||
// target execution count percentile, we compute the minimum number of blocks
|
||||
// needed to reach this target and the minimum execution count of these blocks.
|
||||
struct ProfileSummaryEntry {
|
||||
uint32_t Cutoff; ///< The required percentile of total execution count.
|
||||
uint64_t MinBlockCount; ///< The minimum execution count for this percentile.
|
||||
uint64_t NumBlocks; ///< Number of blocks >= the minumum execution count.
|
||||
};
|
||||
|
||||
class ProfileSummary {
|
||||
// We keep track of the number of times a count appears in the profile and
|
||||
// keep the map sorted in the descending order of counts.
|
||||
std::map<uint64_t, uint32_t, std::greater<uint64_t>> CountFrequencies;
|
||||
std::vector<ProfileSummaryEntry> DetailedSummary;
|
||||
std::vector<uint32_t> DetailedSummaryCutoffs;
|
||||
// Sum of all counts.
|
||||
uint64_t TotalCount;
|
||||
uint64_t MaxBlockCount, MaxFunctionCount;
|
||||
uint32_t NumBlocks, NumFunctions;
|
||||
inline void addCount(uint64_t Count);
|
||||
void computeDetailedSummary();
|
||||
|
||||
public:
|
||||
static const int Scale = 1000000;
|
||||
ProfileSummary(std::vector<uint32_t> Cutoffs)
|
||||
: DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxBlockCount(0),
|
||||
MaxFunctionCount(0), NumBlocks(0), NumFunctions(0) {}
|
||||
inline void addRecord(const InstrProfRecord &);
|
||||
inline std::vector<ProfileSummaryEntry> &getDetailedSummary();
|
||||
uint32_t getNumBlocks() { return NumBlocks; }
|
||||
uint64_t getTotalCount() { return TotalCount; }
|
||||
uint32_t getNumFunctions() { return NumFunctions; }
|
||||
uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
|
||||
uint64_t getMaxBlockCount() { return MaxBlockCount; }
|
||||
};
|
||||
|
||||
// This is called when a count is seen in the profile.
|
||||
void ProfileSummary::addCount(uint64_t Count) {
|
||||
TotalCount += Count;
|
||||
if (Count > MaxBlockCount)
|
||||
MaxBlockCount = Count;
|
||||
NumBlocks++;
|
||||
CountFrequencies[Count]++;
|
||||
}
|
||||
|
||||
void ProfileSummary::addRecord(const InstrProfRecord &R) {
|
||||
NumFunctions++;
|
||||
if (R.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = R.Counts[0];
|
||||
|
||||
for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
|
||||
addCount(R.Counts[I]);
|
||||
}
|
||||
|
||||
std::vector<ProfileSummaryEntry> &ProfileSummary::getDetailedSummary() {
|
||||
if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
|
||||
computeDetailedSummary();
|
||||
return DetailedSummary;
|
||||
}
|
||||
|
||||
namespace IndexedInstrProf {
|
||||
|
||||
enum class HashT : uint32_t {
|
||||
|
@ -599,4 +599,39 @@ void ValueProfData::swapBytesFromHost(support::endianness Endianness) {
|
||||
sys::swapByteOrder<uint32_t>(NumValueKinds);
|
||||
}
|
||||
|
||||
// The argument to this method is a vector of cutoff percentages and the return
|
||||
// value is a vector of (Cutoff, MinBlockCount, NumBlocks) triplets.
|
||||
void ProfileSummary::computeDetailedSummary() {
|
||||
if (DetailedSummaryCutoffs.empty())
|
||||
return;
|
||||
auto Iter = CountFrequencies.begin();
|
||||
auto End = CountFrequencies.end();
|
||||
std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
|
||||
|
||||
uint32_t BlocksSeen = 0;
|
||||
uint64_t CurrSum = 0, Count;
|
||||
|
||||
for (uint32_t Cutoff : DetailedSummaryCutoffs) {
|
||||
assert(Cutoff <= 999999);
|
||||
APInt Temp(128, TotalCount);
|
||||
APInt N(128, Cutoff);
|
||||
APInt D(128, ProfileSummary::Scale);
|
||||
Temp *= N;
|
||||
Temp = Temp.sdiv(D);
|
||||
uint64_t DesiredCount = Temp.getZExtValue();
|
||||
assert(DesiredCount <= TotalCount);
|
||||
while (CurrSum < DesiredCount && Iter != End) {
|
||||
Count = Iter->first;
|
||||
uint32_t Freq = Iter->second;
|
||||
CurrSum += (Count * Freq);
|
||||
BlocksSeen += Freq;
|
||||
Iter++;
|
||||
}
|
||||
assert(CurrSum >= DesiredCount);
|
||||
ProfileSummaryEntry PSE = {Cutoff, Count, BlocksSeen};
|
||||
DetailedSummary.push_back(PSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,105 +36,6 @@ using namespace llvm;
|
||||
|
||||
enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
|
||||
|
||||
///// Profile summary computation ////
|
||||
// The 'show' command displays richer summary of the profile data. The profile
|
||||
// summary is one or more (Cutoff, MinBlockCount, NumBlocks) triplets. Given a
|
||||
// target execution count percentile, we compute the minimum number of blocks
|
||||
// needed to reach this target and the minimum execution count of these blocks.
|
||||
struct ProfileSummaryEntry {
|
||||
uint32_t Cutoff; ///< The required percentile of total execution count.
|
||||
uint64_t MinBlockCount; ///< The minimum execution count for this percentile.
|
||||
uint64_t NumBlocks; ///< Number of blocks >= the minumum execution count.
|
||||
};
|
||||
|
||||
class ProfileSummary {
|
||||
// We keep track of the number of times a count appears in the profile and
|
||||
// keep the map sorted in the descending order of counts.
|
||||
std::map<uint64_t, uint32_t, std::greater<uint64_t>> CountFrequencies;
|
||||
std::vector<ProfileSummaryEntry> DetailedSummary;
|
||||
std::vector<uint32_t> DetailedSummaryCutoffs;
|
||||
// Sum of all counts.
|
||||
uint64_t TotalCount;
|
||||
uint64_t MaxBlockCount, MaxFunctionCount;
|
||||
uint32_t NumBlocks, NumFunctions;
|
||||
void addCount(uint64_t Count);
|
||||
void computeDetailedSummary();
|
||||
|
||||
public:
|
||||
static const int Scale = 1000000;
|
||||
ProfileSummary(std::vector<uint32_t> Cutoffs)
|
||||
: DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxBlockCount(0),
|
||||
MaxFunctionCount(0), NumBlocks(0), NumFunctions(0) {}
|
||||
void addRecord(const InstrProfRecord &);
|
||||
std::vector<ProfileSummaryEntry> &getDetailedSummary();
|
||||
uint32_t getNumBlocks() { return NumBlocks; }
|
||||
uint64_t getTotalCount() { return TotalCount; }
|
||||
uint32_t getNumFunctions() { return NumFunctions; }
|
||||
uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
|
||||
uint64_t getMaxBlockCount() { return MaxBlockCount; }
|
||||
};
|
||||
|
||||
// This is called when a count is seen in the profile.
|
||||
void ProfileSummary::addCount(uint64_t Count) {
|
||||
TotalCount += Count;
|
||||
if (Count > MaxBlockCount)
|
||||
MaxBlockCount = Count;
|
||||
NumBlocks++;
|
||||
CountFrequencies[Count]++;
|
||||
}
|
||||
|
||||
void ProfileSummary::addRecord(const InstrProfRecord &R) {
|
||||
NumFunctions++;
|
||||
if (R.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = R.Counts[0];
|
||||
|
||||
for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
|
||||
addCount(R.Counts[I]);
|
||||
}
|
||||
|
||||
// The argument to this method is a vector of cutoff percentages and the return
|
||||
// value is a vector of (Cutoff, MinBlockCount, NumBlocks) triplets.
|
||||
void ProfileSummary::computeDetailedSummary() {
|
||||
if (DetailedSummaryCutoffs.empty())
|
||||
return;
|
||||
auto Iter = CountFrequencies.begin();
|
||||
auto End = CountFrequencies.end();
|
||||
std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
|
||||
|
||||
uint32_t BlocksSeen = 0;
|
||||
uint64_t CurrSum = 0, Count;
|
||||
|
||||
for (uint32_t Cutoff : DetailedSummaryCutoffs) {
|
||||
assert(Cutoff <= 999999);
|
||||
APInt Temp(128, TotalCount);
|
||||
APInt N(128, Cutoff);
|
||||
APInt D(128, ProfileSummary::Scale);
|
||||
Temp *= N;
|
||||
Temp = Temp.sdiv(D);
|
||||
uint64_t DesiredCount = Temp.getZExtValue();
|
||||
dbgs() << "Cutoff = " << Cutoff << "\n";
|
||||
dbgs() << "DesiredCount = " << DesiredCount << "\n";
|
||||
assert(DesiredCount <= TotalCount);
|
||||
while (CurrSum < DesiredCount && Iter != End) {
|
||||
Count = Iter->first;
|
||||
uint32_t Freq = Iter->second;
|
||||
CurrSum += (Count * Freq);
|
||||
BlocksSeen += Freq;
|
||||
Iter++;
|
||||
}
|
||||
assert(CurrSum >= DesiredCount);
|
||||
ProfileSummaryEntry PSE = {Cutoff, Count, BlocksSeen};
|
||||
DetailedSummary.push_back(PSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ProfileSummaryEntry> &ProfileSummary::getDetailedSummary() {
|
||||
if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
|
||||
computeDetailedSummary();
|
||||
return DetailedSummary;
|
||||
}
|
||||
|
||||
static void exitWithError(const Twine &Message, StringRef Whence = "",
|
||||
StringRef Hint = "") {
|
||||
errs() << "error: ";
|
||||
|
Loading…
Reference in New Issue
Block a user