1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

Refactor profile summary support code. NFC.

Summary computation is not just for instrumented profiling and so I have moved
the ProfileSummary class to ProfileCommon.h (named so to allow code unrelated
to summary but common to instrumented and sampled profiling to be placed there)

Differential Revision: http://reviews.llvm.org/D16661

llvm-svn: 259846
This commit is contained in:
Easwaran Raman 2016-02-04 23:34:31 +00:00
parent e2c912cc97
commit 6960cdccb8
6 changed files with 168 additions and 125 deletions

View File

@ -21,6 +21,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/ProfileData/InstrProfData.inc"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
@ -603,81 +604,6 @@ ValueProfData *
serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,
ValueProfData *Dst);
namespace IndexedInstrProf {
struct Summary;
}
///// 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.
ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinBlockCount,
uint64_t TheNumBlocks)
: Cutoff(TheCutoff), MinBlockCount(TheMinBlockCount),
NumBlocks(TheNumBlocks) {}
};
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, MaxInternalBlockCount, MaxFunctionCount;
uint32_t NumBlocks, NumFunctions;
inline void addCount(uint64_t Count, bool IsEntry);
public:
static const int Scale = 1000000;
ProfileSummary(std::vector<uint32_t> Cutoffs)
: DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxBlockCount(0),
MaxInternalBlockCount(0), MaxFunctionCount(0), NumBlocks(0),
NumFunctions(0) {}
ProfileSummary(const IndexedInstrProf::Summary &S);
inline void addRecord(const InstrProfRecord &);
inline std::vector<ProfileSummaryEntry> &getDetailedSummary();
void computeDetailedSummary();
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; }
uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
};
// This is called when a count is seen in the profile.
void ProfileSummary::addCount(uint64_t Count, bool IsEntry) {
TotalCount += Count;
if (Count > MaxBlockCount)
MaxBlockCount = Count;
if (!IsEntry && Count > MaxInternalBlockCount)
MaxInternalBlockCount = Count;
NumBlocks++;
CountFrequencies[Count]++;
}
void ProfileSummary::addRecord(const InstrProfRecord &R) {
NumFunctions++;
if (R.Counts[0] > MaxFunctionCount)
MaxFunctionCount = R.Counts[0];
for (size_t I = 0, E = R.Counts.size(); I < E; ++I)
addCount(R.Counts[I], (I == 0));
}
std::vector<ProfileSummaryEntry> &ProfileSummary::getDetailedSummary() {
if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
computeDetailedSummary();
return DetailedSummary;
}
namespace IndexedInstrProf {
enum class HashT : uint32_t {

View File

@ -0,0 +1,90 @@
//===-- ProfileCommon.h - Common profiling APIs. ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains data structures and functions common to both instrumented
// and sample profiling.
//
//===----------------------------------------------------------------------===//
#include <cstdint>
#include <map>
#include <vector>
#ifndef LLVM_PROFILEDATA_PROFILE_COMMON_H
#define LLVM_PROFILEDATA_PROFILE_COMMON_H
namespace llvm {
namespace IndexedInstrProf {
struct Summary;
}
class InstrProfRecord;
///// 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.
ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinBlockCount,
uint64_t TheNumBlocks)
: Cutoff(TheCutoff), MinBlockCount(TheMinBlockCount),
NumBlocks(TheNumBlocks) {}
};
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, MaxInternalBlockCount, MaxFunctionCount;
uint32_t NumBlocks, NumFunctions;
inline void addCount(uint64_t Count, bool IsEntry);
public:
static const int Scale = 1000000;
ProfileSummary(std::vector<uint32_t> Cutoffs)
: DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxBlockCount(0),
MaxInternalBlockCount(0), MaxFunctionCount(0), NumBlocks(0),
NumFunctions(0) {}
ProfileSummary(const IndexedInstrProf::Summary &S);
void addRecord(const InstrProfRecord &);
inline std::vector<ProfileSummaryEntry> &getDetailedSummary();
void computeDetailedSummary();
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; }
uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
};
// This is called when a count is seen in the profile.
void ProfileSummary::addCount(uint64_t Count, bool IsEntry) {
TotalCount += Count;
if (Count > MaxBlockCount)
MaxBlockCount = Count;
if (!IsEntry && Count > MaxInternalBlockCount)
MaxInternalBlockCount = Count;
NumBlocks++;
CountFrequencies[Count]++;
}
std::vector<ProfileSummaryEntry> &ProfileSummary::getDetailedSummary() {
if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
computeDetailedSummary();
return DetailedSummary;
}
} // end namespace llvm
#endif

View File

@ -5,6 +5,7 @@ add_llvm_library(LLVMProfileData
CoverageMapping.cpp
CoverageMappingWriter.cpp
CoverageMappingReader.cpp
ProfileSummary.cpp
SampleProf.cpp
SampleProfReader.cpp
SampleProfWriter.cpp

View File

@ -692,54 +692,4 @@ bool getValueProfDataFromInst(const Instruction &Inst,
}
return true;
}
// 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 = 0;
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);
}
}
ProfileSummary::ProfileSummary(const IndexedInstrProf::Summary &S)
: TotalCount(S.get(IndexedInstrProf::Summary::TotalBlockCount)),
MaxBlockCount(S.get(IndexedInstrProf::Summary::MaxBlockCount)),
MaxInternalBlockCount(
S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)),
MaxFunctionCount(S.get(IndexedInstrProf::Summary::MaxFunctionCount)),
NumBlocks(S.get(IndexedInstrProf::Summary::TotalNumBlocks)),
NumFunctions(S.get(IndexedInstrProf::Summary::TotalNumFunctions)) {
for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
Ent.NumBlocks);
}
}
} // end namespace llvm

View File

@ -0,0 +1,75 @@
//=-- Profilesummary.cpp - Profile summary computation ----------------------=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for computing profile summary data.
//
//===----------------------------------------------------------------------===//
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/InstrProf.h"
using namespace llvm;
void ProfileSummary::addRecord(const InstrProfRecord &R) {
NumFunctions++;
if (R.Counts[0] > MaxFunctionCount)
MaxFunctionCount = R.Counts[0];
for (size_t I = 0, E = R.Counts.size(); I < E; ++I)
addCount(R.Counts[I], (I == 0));
}
// 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 = 0;
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);
}
}
ProfileSummary::ProfileSummary(const IndexedInstrProf::Summary &S)
: TotalCount(S.get(IndexedInstrProf::Summary::TotalBlockCount)),
MaxBlockCount(S.get(IndexedInstrProf::Summary::MaxBlockCount)),
MaxInternalBlockCount(
S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)),
MaxFunctionCount(S.get(IndexedInstrProf::Summary::MaxFunctionCount)),
NumBlocks(S.get(IndexedInstrProf::Summary::TotalNumBlocks)),
NumFunctions(S.get(IndexedInstrProf::Summary::TotalNumFunctions)) {
for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
Ent.NumBlocks);
}
}

View File

@ -17,6 +17,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/ProfileData/SampleProfWriter.h"
#include "llvm/Support/CommandLine.h"