mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +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:
parent
e2c912cc97
commit
6960cdccb8
@ -21,6 +21,7 @@
|
|||||||
#include "llvm/ADT/StringSet.h"
|
#include "llvm/ADT/StringSet.h"
|
||||||
#include "llvm/IR/GlobalValue.h"
|
#include "llvm/IR/GlobalValue.h"
|
||||||
#include "llvm/ProfileData/InstrProfData.inc"
|
#include "llvm/ProfileData/InstrProfData.inc"
|
||||||
|
#include "llvm/ProfileData/ProfileCommon.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/ErrorOr.h"
|
#include "llvm/Support/ErrorOr.h"
|
||||||
@ -603,81 +604,6 @@ ValueProfData *
|
|||||||
serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,
|
serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,
|
||||||
ValueProfData *Dst);
|
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 {
|
namespace IndexedInstrProf {
|
||||||
|
|
||||||
enum class HashT : uint32_t {
|
enum class HashT : uint32_t {
|
||||||
|
90
include/llvm/ProfileData/ProfileCommon.h
Normal file
90
include/llvm/ProfileData/ProfileCommon.h
Normal 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
|
@ -5,6 +5,7 @@ add_llvm_library(LLVMProfileData
|
|||||||
CoverageMapping.cpp
|
CoverageMapping.cpp
|
||||||
CoverageMappingWriter.cpp
|
CoverageMappingWriter.cpp
|
||||||
CoverageMappingReader.cpp
|
CoverageMappingReader.cpp
|
||||||
|
ProfileSummary.cpp
|
||||||
SampleProf.cpp
|
SampleProf.cpp
|
||||||
SampleProfReader.cpp
|
SampleProfReader.cpp
|
||||||
SampleProfWriter.cpp
|
SampleProfWriter.cpp
|
||||||
|
@ -692,54 +692,4 @@ bool getValueProfDataFromInst(const Instruction &Inst,
|
|||||||
}
|
}
|
||||||
return true;
|
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
|
} // end namespace llvm
|
||||||
|
75
lib/ProfileData/ProfileSummary.cpp
Normal file
75
lib/ProfileData/ProfileSummary.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/ProfileData/InstrProfReader.h"
|
#include "llvm/ProfileData/InstrProfReader.h"
|
||||||
#include "llvm/ProfileData/InstrProfWriter.h"
|
#include "llvm/ProfileData/InstrProfWriter.h"
|
||||||
|
#include "llvm/ProfileData/ProfileCommon.h"
|
||||||
#include "llvm/ProfileData/SampleProfReader.h"
|
#include "llvm/ProfileData/SampleProfReader.h"
|
||||||
#include "llvm/ProfileData/SampleProfWriter.h"
|
#include "llvm/ProfileData/SampleProfWriter.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user