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

Re-land "[ThinLTO] Add call edges' relative block frequency to per-module summary."

It was reverted after buildbot regressions.

Original commit message:

This allows relative block frequency of call edges to be passed
to the thinlink stage where it will be used to compute synthetic
entry counts of functions.

llvm-svn: 323460
This commit is contained in:
Easwaran Raman 2018-01-25 19:27:17 +00:00
parent f6c223bd56
commit 3831ff54c8
7 changed files with 93 additions and 31 deletions

View File

@ -256,6 +256,11 @@ enum GlobalValueSummarySymtabCodes {
// strings in strtab. // strings in strtab.
// [n * name] // [n * name]
FS_CFI_FUNCTION_DECLS = 18, FS_CFI_FUNCTION_DECLS = 18,
// Per-module summary that also adds relative block frequency to callee info.
// PERMODULE_RELBF: [valueid, flags, instcount, numrefs,
// numrefs x valueid,
// n x (valueid, relblockfreq)]
FS_PERMODULE_RELBF = 19,
}; };
enum MetadataCodes { enum MetadataCodes {

View File

@ -25,6 +25,7 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cassert> #include <cassert>
@ -54,13 +55,30 @@ struct CalleeInfo {
Hot = 3, Hot = 3,
Critical = 4 Critical = 4
}; };
HotnessType Hotness = HotnessType::Unknown;
CalleeInfo() = default; // The size of the bit-field might need to be adjusted if more values are
explicit CalleeInfo(HotnessType Hotness) : Hotness(Hotness) {} // added to HotnessType enum.
uint32_t Hotness : 3;
uint32_t RelBlockFreq : 29;
static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1;
CalleeInfo()
: Hotness(static_cast<uint32_t>(HotnessType::Unknown)), RelBlockFreq(0) {}
explicit CalleeInfo(HotnessType Hotness, uint64_t RelBF)
: Hotness(static_cast<uint32_t>(Hotness)), RelBlockFreq(RelBF) {}
void updateHotness(const HotnessType OtherHotness) { void updateHotness(const HotnessType OtherHotness) {
Hotness = std::max(Hotness, OtherHotness); Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness));
}
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);
Sum = std::min(Sum, uint64_t(MaxRelBlockFreq));
RelBlockFreq = static_cast<uint32_t>(Sum);
} }
}; };

View File

@ -273,9 +273,24 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
// to record the call edge to the alias in that case. Eventually // to record the call edge to the alias in that case. Eventually
// an alias summary will be created to associate the alias and // an alias summary will be created to associate the alias and
// aliasee. // aliasee.
CallGraphEdges[Index.getOrInsertValueInfo( auto &ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo(
cast<GlobalValue>(CalledValue))] cast<GlobalValue>(CalledValue))];
.updateHotness(Hotness); ValueInfo.updateHotness(Hotness);
// 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);
}
} else { } else {
// Skip inline assembly calls. // Skip inline assembly calls.
if (CI && CI->isInlineAsm()) if (CI && CI->isInlineAsm())

View File

@ -743,7 +743,8 @@ private:
std::vector<ValueInfo> makeRefList(ArrayRef<uint64_t> Record); std::vector<ValueInfo> makeRefList(ArrayRef<uint64_t> Record);
std::vector<FunctionSummary::EdgeTy> makeCallList(ArrayRef<uint64_t> Record, std::vector<FunctionSummary::EdgeTy> makeCallList(ArrayRef<uint64_t> Record,
bool IsOldProfileFormat, bool IsOldProfileFormat,
bool HasProfile); bool HasProfile,
bool HasRelBF);
Error parseEntireSummary(unsigned ID); Error parseEntireSummary(unsigned ID);
Error parseModuleStringTable(); Error parseModuleStringTable();
@ -5047,12 +5048,15 @@ ModuleSummaryIndexBitcodeReader::makeRefList(ArrayRef<uint64_t> Record) {
return Ret; return Ret;
} }
std::vector<FunctionSummary::EdgeTy> ModuleSummaryIndexBitcodeReader::makeCallList( std::vector<FunctionSummary::EdgeTy>
ArrayRef<uint64_t> Record, bool IsOldProfileFormat, bool HasProfile) { ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record,
bool IsOldProfileFormat,
bool HasProfile, bool HasRelBF) {
std::vector<FunctionSummary::EdgeTy> Ret; std::vector<FunctionSummary::EdgeTy> Ret;
Ret.reserve(Record.size()); Ret.reserve(Record.size());
for (unsigned I = 0, E = Record.size(); I != E; ++I) { for (unsigned I = 0, E = Record.size(); I != E; ++I) {
CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
uint64_t RelBF = 0;
ValueInfo Callee = getValueInfoFromValueId(Record[I]).first; ValueInfo Callee = getValueInfoFromValueId(Record[I]).first;
if (IsOldProfileFormat) { if (IsOldProfileFormat) {
I += 1; // Skip old callsitecount field I += 1; // Skip old callsitecount field
@ -5060,7 +5064,9 @@ std::vector<FunctionSummary::EdgeTy> ModuleSummaryIndexBitcodeReader::makeCallLi
I += 1; // Skip old profilecount field I += 1; // Skip old profilecount field
} else if (HasProfile) } else if (HasProfile)
Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]); Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]);
Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo{Hotness}}); else if (HasRelBF)
RelBF = Record[++I];
Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo(Hotness, RelBF)});
} }
return Ret; return Ret;
} }
@ -5139,7 +5145,11 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
// FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs, // FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs,
// numrefs x valueid, // numrefs x valueid,
// n x (valueid, hotness)] // n x (valueid, hotness)]
// FS_PERMODULE_RELBF: [valueid, flags, instcount, fflags, numrefs,
// numrefs x valueid,
// n x (valueid, relblockfreq)]
case bitc::FS_PERMODULE: case bitc::FS_PERMODULE:
case bitc::FS_PERMODULE_RELBF:
case bitc::FS_PERMODULE_PROFILE: { case bitc::FS_PERMODULE_PROFILE: {
unsigned ValueID = Record[0]; unsigned ValueID = Record[0];
uint64_t RawFlags = Record[1]; uint64_t RawFlags = Record[1];
@ -5165,9 +5175,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
std::vector<ValueInfo> Refs = makeRefList( std::vector<ValueInfo> Refs = makeRefList(
ArrayRef<uint64_t>(Record).slice(RefListStartIndex, NumRefs)); ArrayRef<uint64_t>(Record).slice(RefListStartIndex, NumRefs));
bool HasProfile = (BitCode == bitc::FS_PERMODULE_PROFILE); bool HasProfile = (BitCode == bitc::FS_PERMODULE_PROFILE);
bool HasRelBF = (BitCode == bitc::FS_PERMODULE_RELBF);
std::vector<FunctionSummary::EdgeTy> Calls = makeCallList( std::vector<FunctionSummary::EdgeTy> Calls = makeCallList(
ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
IsOldProfileFormat, HasProfile); IsOldProfileFormat, HasProfile, HasRelBF);
auto FS = llvm::make_unique<FunctionSummary>( auto FS = llvm::make_unique<FunctionSummary>(
Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs), Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs),
std::move(Calls), std::move(PendingTypeTests), std::move(Calls), std::move(PendingTypeTests),
@ -5259,7 +5270,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
bool HasProfile = (BitCode == bitc::FS_COMBINED_PROFILE); bool HasProfile = (BitCode == bitc::FS_COMBINED_PROFILE);
std::vector<FunctionSummary::EdgeTy> Edges = makeCallList( std::vector<FunctionSummary::EdgeTy> Edges = makeCallList(
ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
IsOldProfileFormat, HasProfile); IsOldProfileFormat, HasProfile, false);
ValueInfo VI = getValueInfoFromValueId(ValueID).first; ValueInfo VI = getValueInfoFromValueId(ValueID).first;
auto FS = llvm::make_unique<FunctionSummary>( auto FS = llvm::make_unique<FunctionSummary>(
Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs), Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs),

View File

@ -86,6 +86,9 @@ static cl::opt<unsigned>
cl::desc("Number of metadatas above which we emit an index " cl::desc("Number of metadatas above which we emit an index "
"to enable lazy-loading")); "to enable lazy-loading"));
cl::opt<bool> WriteRelBFToSummary(
"write-relbf-to-summary", cl::Hidden, cl::init(false),
cl::desc("Write relative block frequency to function summary "));
namespace { namespace {
/// These are manifest constants used by the bitcode writer. They do not need to /// These are manifest constants used by the bitcode writer. They do not need to
@ -3378,11 +3381,15 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
NameVals.push_back(getValueId(ECI.first)); NameVals.push_back(getValueId(ECI.first));
if (HasProfileData) if (HasProfileData)
NameVals.push_back(static_cast<uint8_t>(ECI.second.Hotness)); NameVals.push_back(static_cast<uint8_t>(ECI.second.Hotness));
else if (WriteRelBFToSummary)
NameVals.push_back(ECI.second.RelBlockFreq);
} }
unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev); unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
unsigned Code = unsigned Code =
(HasProfileData ? bitc::FS_PERMODULE_PROFILE : bitc::FS_PERMODULE); (HasProfileData ? bitc::FS_PERMODULE_PROFILE
: (WriteRelBFToSummary ? bitc::FS_PERMODULE_RELBF
: bitc::FS_PERMODULE));
// Emit the finished record. // Emit the finished record.
Stream.EmitRecord(Code, NameVals, FSAbbrev); Stream.EmitRecord(Code, NameVals, FSAbbrev);
@ -3448,21 +3455,8 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
ArrayRef<uint64_t>{GVI.second, GVI.first}); ArrayRef<uint64_t>{GVI.second, GVI.first});
} }
// Abbrev for FS_PERMODULE.
auto Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
// numrefs x valueid, n x (valueid)
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv));
// Abbrev for FS_PERMODULE_PROFILE. // Abbrev for FS_PERMODULE_PROFILE.
Abbv = std::make_shared<BitCodeAbbrev>(); auto Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE)); Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
@ -3474,6 +3468,22 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv)); unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv));
// Abbrev for FS_PERMODULE or FS_PERMODULE_RELBF.
Abbv = std::make_shared<BitCodeAbbrev>();
if (WriteRelBFToSummary)
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_RELBF));
else
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
// numrefs x valueid, n x (valueid [, rel_block_freq])
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv));
// Abbrev for FS_PERMODULE_GLOBALVAR_INIT_REFS. // Abbrev for FS_PERMODULE_GLOBALVAR_INIT_REFS.
Abbv = std::make_shared<BitCodeAbbrev>(); Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS)); Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS));
@ -3675,7 +3685,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
bool HasProfileData = false; bool HasProfileData = false;
for (auto &EI : FS->calls()) { for (auto &EI : FS->calls()) {
HasProfileData |= EI.second.Hotness != CalleeInfo::HotnessType::Unknown; HasProfileData |=
EI.second.getHotness() != CalleeInfo::HotnessType::Unknown;
if (HasProfileData) if (HasProfileData)
break; break;
} }

View File

@ -269,7 +269,7 @@ static void computeImportForFunction(
}; };
const auto NewThreshold = const auto NewThreshold =
Threshold * GetBonusMultiplier(Edge.second.Hotness); Threshold * GetBonusMultiplier(Edge.second.getHotness());
auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold, auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold,
Summary.modulePath()); Summary.modulePath());
@ -293,7 +293,8 @@ static void computeImportForFunction(
return Threshold * ImportInstrFactor; return Threshold * ImportInstrFactor;
}; };
bool IsHotCallsite = Edge.second.Hotness == CalleeInfo::HotnessType::Hot; bool IsHotCallsite =
Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite); const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
auto ExportModulePath = ResolvedCalleeSummary->modulePath(); auto ExportModulePath = ResolvedCalleeSummary->modulePath();

View File

@ -306,6 +306,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
return nullptr; return nullptr;
STRINGIFY_CODE(FS, PERMODULE) STRINGIFY_CODE(FS, PERMODULE)
STRINGIFY_CODE(FS, PERMODULE_PROFILE) STRINGIFY_CODE(FS, PERMODULE_PROFILE)
STRINGIFY_CODE(FS, PERMODULE_RELBF)
STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS)
STRINGIFY_CODE(FS, COMBINED) STRINGIFY_CODE(FS, COMBINED)
STRINGIFY_CODE(FS, COMBINED_PROFILE) STRINGIFY_CODE(FS, COMBINED_PROFILE)