Skip to content

Commit

Permalink
ThinLTO: Make aliases explicit in the summary
Browse files Browse the repository at this point in the history
To be able to work accurately on the reference graph when taking
decision about internalizing, promoting, renaming, etc. We need
to have the alias information explicit.

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

From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 266517
  • Loading branch information
joker-eph committed Apr 16, 2016
1 parent d82f494 commit 2d28f7a
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 41 deletions.
4 changes: 4 additions & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Expand Up @@ -213,6 +213,10 @@ enum GlobalValueSummarySymtabCodes {
FS_COMBINED_PROFILE = 5,
// COMBINED_GLOBALVAR_INIT_REFS: [modid, linkage, n x valueid]
FS_COMBINED_GLOBALVAR_INIT_REFS = 6,
// ALIAS: [valueid, linkage, valueid]
FS_ALIAS = 7,
// COMBINED_ALIAS: [modid, linkage, offset]
FS_COMBINED_ALIAS = 8,
};

enum MetadataCodes {
Expand Down
30 changes: 28 additions & 2 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Expand Up @@ -93,7 +93,7 @@ struct ValueInfo {
class GlobalValueSummary {
public:
/// \brief Sububclass discriminator (for dyn_cast<> et al.)
enum SummaryKind { FunctionKind, GlobalVarKind };
enum SummaryKind { AliasKind, FunctionKind, GlobalVarKind };

private:
/// Kind of summary for use in dyn_cast<> et al.
Expand Down Expand Up @@ -164,6 +164,32 @@ class GlobalValueSummary {
const std::vector<ValueInfo> &refs() const { return RefEdgeList; }
};

/// \brief Alias summary information.
class AliasSummary : public GlobalValueSummary {
GlobalValueSummary *AliaseeSummary;

public:
/// Summary constructors.
AliasSummary(GlobalValue::LinkageTypes Linkage)
: GlobalValueSummary(AliasKind, Linkage) {}

/// Check if this is an alias summary.
static bool classof(const GlobalValueSummary *GVS) {
return GVS->getSummaryKind() == AliasKind;
}

void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; }

const GlobalValueSummary &getAliasee() const {
return const_cast<AliasSummary *>(this)->getAliasee();
}

GlobalValueSummary &getAliasee() {
assert(AliaseeSummary && "Unexpected missing aliasee summary");
return *AliaseeSummary;
}
};

/// \brief Function summary information to aid decisions and implementation of
/// importing.
class FunctionSummary : public GlobalValueSummary {
Expand Down Expand Up @@ -439,7 +465,7 @@ class ModuleSummaryIndex {
/// (GUID -> Summary).
void collectDefinedFunctionsForModule(
StringRef ModulePath,
std::map<GlobalValue::GUID, FunctionSummary *> &FunctionInfoMap) const;
std::map<GlobalValue::GUID, GlobalValueSummary *> &FunctionInfoMap) const;
};

} // End llvm namespace
Expand Down
51 changes: 51 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Expand Up @@ -5865,6 +5865,35 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
Info->setSummary(std::move(FS));
break;
}
// FS_ALIAS: [valueid, linkage, valueid]
// Aliases must be emitted (and parsed) after all FS_PERMODULE entries, as
// they expect all aliasee summaries to be available.
case bitc::FS_ALIAS: {
unsigned ValueID = Record[0];
uint64_t RawLinkage = Record[1];
unsigned AliaseeID = Record[2];
std::unique_ptr<AliasSummary> AS =
llvm::make_unique<AliasSummary>(getDecodedLinkage(RawLinkage));
// The module path string ref set in the summary must be owned by the
// index's module string table. Since we don't have a module path
// string table section in the per-module index, we create a single
// module path string table entry with an empty (0) ID to take
// ownership.
AS->setModulePath(
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());

GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID);
auto *AliaseeInfo = TheIndex->getGlobalValueInfo(AliaseeGUID);
if (!AliaseeInfo->summary())
return error("Alias expects aliasee summary to be parsed");
AS->setAliasee(AliaseeInfo->summary());

GlobalValue::GUID GUID = getGUIDFromValueId(ValueID);
auto *Info = TheIndex->getGlobalValueInfo(GUID);
assert(!Info->summary() && "Expected a single summary per VST entry");
Info->setSummary(std::move(AS));
break;
}
// FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, linkage, n x valueid]
case bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS: {
unsigned ValueID = Record[0];
Expand Down Expand Up @@ -5923,6 +5952,28 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
Combined = true;
break;
}
// FS_COMBINED_ALIAS: [modid, linkage, offset]
// Aliases must be emitted (and parsed) after all FS_COMBINED entries, as
// they expect all aliasee summaries to be available.
case bitc::FS_COMBINED_ALIAS: {
uint64_t ModuleId = Record[0];
uint64_t RawLinkage = Record[1];
uint64_t AliaseeSummaryOffset = Record[2];
std::unique_ptr<AliasSummary> AS =
llvm::make_unique<AliasSummary>(getDecodedLinkage(RawLinkage));
AS->setModulePath(ModuleIdMap[ModuleId]);

auto *AliaseeInfo = getInfoFromSummaryOffset(AliaseeSummaryOffset);
if (!AliaseeInfo->summary())
return error("Alias expects aliasee summary to be parsed");
AS->setAliasee(AliaseeInfo->summary());

auto *Info = getInfoFromSummaryOffset(CurRecordBit);
assert(!Info->summary() && "Expected a single summary per VST entry");
Info->setSummary(std::move(AS));
Combined = true;
break;
}
// FS_COMBINED_GLOBALVAR_INIT_REFS: [modid, linkage, n x valueid]
case bitc::FS_COMBINED_GLOBALVAR_INIT_REFS: {
uint64_t ModuleId = Record[0];
Expand Down
70 changes: 67 additions & 3 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Expand Up @@ -2925,16 +2925,24 @@ static void WritePerModuleGlobalValueSummary(const Module *M,
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned FSModRefsAbbrev = Stream.EmitAbbrev(Abbv);

// Abbrev for FS_ALIAS.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_ALIAS));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
unsigned FSAliasAbbrev = Stream.EmitAbbrev(Abbv);

SmallVector<uint64_t, 64> NameVals;
// Iterate over the list of functions instead of the Index to
// ensure the ordering is stable.
for (const Function &F : *M) {
if (F.isDeclaration())
continue;
// Skip anonymous functions. We will emit a function summary for
// any aliases below.
// Summary emission does not support anonymous functions, they have to
// renamed using the anonymous function renaming pass.
if (!F.hasName())
continue;
report_fatal_error("Unexpected anonymous function when writing summary");

auto *Info = Index.getGlobalValueInfo(F);
WritePerModuleFunctionSummaryRecord(
Expand All @@ -2948,6 +2956,20 @@ static void WritePerModuleGlobalValueSummary(const Module *M,
for (const GlobalVariable &G : M->globals())
WriteModuleLevelReferences(G, Index, VE, NameVals, FSModRefsAbbrev, Stream);

for (const GlobalAlias &A : M->aliases()) {
auto *Aliasee = A.getBaseObject();
if (!Aliasee->hasName())
// Nameless function don't have an entry in the summary, skip it.
continue;
auto AliasId = VE.getValueID(&A);
auto AliaseeId = VE.getValueID(Aliasee);
NameVals.push_back(AliasId);
NameVals.push_back(getEncodedLinkage(A.getLinkage()));
NameVals.push_back(AliaseeId);
Stream.EmitRecord(bitc::FS_ALIAS, NameVals, FSAliasAbbrev);
NameVals.clear();
}

Stream.ExitBlock();
}

Expand Down Expand Up @@ -2991,11 +3013,31 @@ static void WriteCombinedGlobalValueSummary(
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned FSModRefsAbbrev = Stream.EmitAbbrev(Abbv);

// Abbrev for FS_COMBINED_ALIAS.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_ALIAS));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // offset
unsigned FSAliasAbbrev = Stream.EmitAbbrev(Abbv);

// The aliases are emitted as a post-pass, and will point to the summary
// offset id of the aliasee. For this purpose we need to be able to get back
// from the summary to the offset
SmallVector<GlobalValueInfo *, 64> Aliases;
DenseMap<const GlobalValueSummary *, uint64_t> SummaryToOffsetMap;

SmallVector<uint64_t, 64> NameVals;
for (const auto &FII : Index) {
for (auto &FI : FII.second) {
GlobalValueSummary *S = FI->summary();
assert(S);
if (isa<AliasSummary>(S)) {
// Will process aliases as a post-pass because the reader wants all
// global to be loaded first.
Aliases.push_back(FI.get());
continue;
}

if (auto *VS = dyn_cast<GlobalVarSummary>(S)) {
NameVals.push_back(Index.getModuleId(VS->modulePath()));
Expand All @@ -3018,6 +3060,8 @@ static void WriteCombinedGlobalValueSummary(
// reader will invoke readRecord after the abbrev id read.
FI->setBitcodeIndex(Stream.GetCurrentBitNo() +
Stream.GetAbbrevIDWidth());
// Store temporarily the offset in the map for a possible alias.
SummaryToOffsetMap[S] = FI->bitcodeIndex();

// Emit the finished record.
Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
Expand Down Expand Up @@ -3069,6 +3113,8 @@ static void WriteCombinedGlobalValueSummary(
// in the VST entry. Add the current code size since the
// reader will invoke readRecord after the abbrev id read.
FI->setBitcodeIndex(Stream.GetCurrentBitNo() + Stream.GetAbbrevIDWidth());
// Store temporarily the offset in the map for a possible alias.
SummaryToOffsetMap[S] = FI->bitcodeIndex();

unsigned FSAbbrev =
(HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
Expand All @@ -3081,6 +3127,24 @@ static void WriteCombinedGlobalValueSummary(
}
}

for (auto GVI : Aliases) {
AliasSummary *AS = cast<AliasSummary>(GVI->summary());
NameVals.push_back(Index.getModuleId(AS->modulePath()));
NameVals.push_back(getEncodedLinkage(AS->linkage()));
auto AliaseeOffset = SummaryToOffsetMap[&AS->getAliasee()];
assert(AliaseeOffset);
NameVals.push_back(AliaseeOffset);

// Record the starting offset of this summary entry for use
// in the VST entry. Add the current code size since the
// reader will invoke readRecord after the abbrev id read.
GVI->setBitcodeIndex(Stream.GetCurrentBitNo() + Stream.GetAbbrevIDWidth());

// Emit the finished record.
Stream.EmitRecord(bitc::FS_COMBINED_ALIAS, NameVals, FSAliasAbbrev);
NameVals.clear();
}

Stream.ExitBlock();
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/ModuleSummaryIndex.cpp
Expand Up @@ -73,7 +73,7 @@ void ModuleSummaryIndex::removeEmptySummaryEntries() {
// (GUID -> Summary).
void ModuleSummaryIndex::collectDefinedFunctionsForModule(
StringRef ModulePath,
std::map<GlobalValue::GUID, FunctionSummary *> &FunctionInfoMap) const {
std::map<GlobalValue::GUID, GlobalValueSummary *> &FunctionInfoMap) const {
for (auto &GlobalList : *this) {
auto GUID = GlobalList.first;
for (auto &GlobInfo : GlobalList.second) {
Expand Down

0 comments on commit 2d28f7a

Please sign in to comment.