summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h2
-rw-r--r--llvm/include/llvm/IR/ModuleSummaryIndex.h12
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp88
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp14
-rw-r--r--llvm/test/Bitcode/thinlto-function-summary-originalnames.ll24
-rw-r--r--llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp1
6 files changed, 116 insertions, 25 deletions
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 14ba1586e48..71f3cc80dd7 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -217,6 +217,8 @@ enum GlobalValueSummarySymtabCodes {
FS_ALIAS = 7,
// COMBINED_ALIAS: [modid, linkage, offset]
FS_COMBINED_ALIAS = 8,
+ // COMBINED_ORIGINAL_NAME: [original_name_hash]
+ FS_COMBINED_ORIGINAL_NAME = 9,
};
enum MetadataCodes {
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 41c567a2b0d..e05ef67ded2 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -96,6 +96,11 @@ private:
/// Kind of summary for use in dyn_cast<> et al.
SummaryKind Kind;
+ /// This is the hash of the name of the symbol in the original file. It is
+ /// identical to the GUID for global symbols, but differs for local since the
+ /// GUID includes the module level id in the hash.
+ GlobalValue::GUID OriginalName;
+
/// \brief Path of module IR containing value's definition, used to locate
/// module during importing.
///
@@ -128,6 +133,13 @@ protected:
public:
virtual ~GlobalValueSummary() = default;
+ /// Returns the hash of the original name, it is identical to the GUID for
+ /// externally visible symbols, but not for local ones.
+ GlobalValue::GUID getOriginalName() { return OriginalName; }
+
+ /// Initialize the original name hash in this summary.
+ void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; }
+
/// Which kind of summary subclass this is.
SummaryKind getSummaryKind() const { return Kind; }
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 521256005cb..cbacf8127d4 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -487,7 +487,10 @@ class ModuleSummaryIndexBitcodeReader {
// call graph edges read from the function summary from referencing
// callees by their ValueId to using the GUID instead, which is how
// they are recorded in the summary index being built.
- DenseMap<unsigned, GlobalValue::GUID> ValueIdToCallGraphGUIDMap;
+ // We save a second GUID which is the same as the first one, but ignoring the
+ // linkage, i.e. for value other than local linkage they are identical.
+ DenseMap<unsigned, std::pair<GlobalValue::GUID, GlobalValue::GUID>>
+ ValueIdToCallGraphGUIDMap;
/// Map to save the association between summary offset in the VST to the
/// GlobalValueInfo object created when parsing it. Used to access the
@@ -543,7 +546,8 @@ private:
std::error_code initStream(std::unique_ptr<DataStreamer> Streamer);
std::error_code initStreamFromBuffer();
std::error_code initLazyStream(std::unique_ptr<DataStreamer> Streamer);
- GlobalValue::GUID getGUIDFromValueId(unsigned ValueId);
+ std::pair<GlobalValue::GUID, GlobalValue::GUID>
+ getGUIDFromValueId(unsigned ValueId);
GlobalValueInfo *getInfoFromSummaryOffset(uint64_t Offset);
};
} // end anonymous namespace
@@ -5699,7 +5703,7 @@ void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; }
void ModuleSummaryIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
-GlobalValue::GUID
+std::pair<GlobalValue::GUID, GlobalValue::GUID>
ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);
assert(VGI != ValueIdToCallGraphGUIDMap.end());
@@ -5763,13 +5767,19 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
auto VLI = ValueIdToLinkageMap.find(ValueID);
assert(VLI != ValueIdToLinkageMap.end() &&
"No linkage found for VST entry?");
- std::string GlobalId = GlobalValue::getGlobalIdentifier(
- ValueName, VLI->second, SourceFileName);
+ auto Linkage = VLI->second;
+ std::string GlobalId =
+ GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName);
auto ValueGUID = GlobalValue::getGUID(GlobalId);
+ auto OriginalNameID = ValueGUID;
+ if (GlobalValue::isLocalLinkage(Linkage))
+ OriginalNameID = GlobalValue::getGUID(ValueName);
if (PrintSummaryGUIDs)
- dbgs() << "GUID " << ValueGUID << " is " << ValueName << "\n";
+ dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is "
+ << ValueName << "\n";
TheIndex->addGlobalValueInfo(ValueGUID, std::move(GlobalValInfo));
- ValueIdToCallGraphGUIDMap[ValueID] = ValueGUID;
+ ValueIdToCallGraphGUIDMap[ValueID] =
+ std::make_pair(ValueGUID, OriginalNameID);
ValueName.clear();
break;
}
@@ -5785,13 +5795,19 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
auto VLI = ValueIdToLinkageMap.find(ValueID);
assert(VLI != ValueIdToLinkageMap.end() &&
"No linkage found for VST entry?");
+ auto Linkage = VLI->second;
std::string FunctionGlobalId = GlobalValue::getGlobalIdentifier(
ValueName, VLI->second, SourceFileName);
auto FunctionGUID = GlobalValue::getGUID(FunctionGlobalId);
+ auto OriginalNameID = FunctionGUID;
+ if (GlobalValue::isLocalLinkage(Linkage))
+ OriginalNameID = GlobalValue::getGUID(ValueName);
if (PrintSummaryGUIDs)
- dbgs() << "GUID " << FunctionGUID << " is " << ValueName << "\n";
+ dbgs() << "GUID " << FunctionGUID << "(" << OriginalNameID << ") is "
+ << ValueName << "\n";
TheIndex->addGlobalValueInfo(FunctionGUID, std::move(FuncInfo));
- ValueIdToCallGraphGUIDMap[ValueID] = FunctionGUID;
+ ValueIdToCallGraphGUIDMap[ValueID] =
+ std::make_pair(FunctionGUID, OriginalNameID);
ValueName.clear();
break;
@@ -5805,14 +5821,19 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
llvm::make_unique<GlobalValueInfo>(GlobalValSummaryOffset);
SummaryOffsetToInfoMap[GlobalValSummaryOffset] = GlobalValInfo.get();
TheIndex->addGlobalValueInfo(GlobalValGUID, std::move(GlobalValInfo));
- ValueIdToCallGraphGUIDMap[ValueID] = GlobalValGUID;
+ // The "original name", which is the second value of the pair will be
+ // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index.
+ ValueIdToCallGraphGUIDMap[ValueID] =
+ std::make_pair(GlobalValGUID, GlobalValGUID);
break;
}
case bitc::VST_CODE_COMBINED_ENTRY: {
// VST_CODE_COMBINED_ENTRY: [valueid, refguid]
unsigned ValueID = Record[0];
GlobalValue::GUID RefGUID = Record[1];
- ValueIdToCallGraphGUIDMap[ValueID] = RefGUID;
+ // The "original name", which is the second value of the pair will be
+ // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index.
+ ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID);
break;
}
}
@@ -5976,7 +5997,9 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
return error("Invalid record");
SmallVector<uint64_t, 64> Record;
-
+ // Keep around the last seen summary to be used when we see an optional
+ // "OriginalName" attachement.
+ GlobalValueSummary *LastSeenSummary = nullptr;
bool Combined = false;
while (1) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -6041,7 +6064,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
"Record size inconsistent with number of references");
for (unsigned I = 4, E = CallGraphEdgeStartIndex; I != E; ++I) {
unsigned RefValueId = Record[I];
- GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId);
+ GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
FS->addRefEdge(RefGUID);
}
bool HasProfile = (BitCode == bitc::FS_PERMODULE_PROFILE);
@@ -6050,12 +6073,13 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
unsigned CalleeValueId = Record[I];
unsigned CallsiteCount = Record[++I];
uint64_t ProfileCount = HasProfile ? Record[++I] : 0;
- GlobalValue::GUID CalleeGUID = getGUIDFromValueId(CalleeValueId);
+ GlobalValue::GUID CalleeGUID = getGUIDFromValueId(CalleeValueId).first;
FS->addCallGraphEdge(CalleeGUID,
CalleeInfo(CallsiteCount, ProfileCount));
}
- GlobalValue::GUID GUID = getGUIDFromValueId(ValueID);
- auto *Info = TheIndex->getGlobalValueInfo(GUID);
+ auto GUID = getGUIDFromValueId(ValueID);
+ FS->setOriginalName(GUID.second);
+ auto *Info = TheIndex->getGlobalValueInfo(GUID.first);
assert(!Info->summary() && "Expected a single summary per VST entry");
Info->setSummary(std::move(FS));
break;
@@ -6077,14 +6101,15 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
AS->setModulePath(
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
- GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID);
+ GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;
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);
+ auto GUID = getGUIDFromValueId(ValueID);
+ AS->setOriginalName(GUID.second);
+ auto *Info = TheIndex->getGlobalValueInfo(GUID.first);
assert(!Info->summary() && "Expected a single summary per VST entry");
Info->setSummary(std::move(AS));
break;
@@ -6099,11 +6124,12 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
for (unsigned I = 2, E = Record.size(); I != E; ++I) {
unsigned RefValueId = Record[I];
- GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId);
+ GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
FS->addRefEdge(RefGUID);
}
- GlobalValue::GUID GUID = getGUIDFromValueId(ValueID);
- auto *Info = TheIndex->getGlobalValueInfo(GUID);
+ auto GUID = getGUIDFromValueId(ValueID);
+ FS->setOriginalName(GUID.second);
+ auto *Info = TheIndex->getGlobalValueInfo(GUID.first);
assert(!Info->summary() && "Expected a single summary per VST entry");
Info->setSummary(std::move(FS));
break;
@@ -6121,6 +6147,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
unsigned NumRefs = Record[3];
std::unique_ptr<FunctionSummary> FS = llvm::make_unique<FunctionSummary>(
getDecodedLinkage(RawLinkage), InstCount);
+ LastSeenSummary = FS.get();
FS->setModulePath(ModuleIdMap[ModuleId]);
static int RefListStartIndex = 4;
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
@@ -6128,7 +6155,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
"Record size inconsistent with number of references");
for (unsigned I = 4, E = CallGraphEdgeStartIndex; I != E; ++I) {
unsigned RefValueId = Record[I];
- GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId);
+ GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
FS->addRefEdge(RefGUID);
}
bool HasProfile = (BitCode == bitc::FS_COMBINED_PROFILE);
@@ -6137,7 +6164,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
unsigned CalleeValueId = Record[I];
unsigned CallsiteCount = Record[++I];
uint64_t ProfileCount = HasProfile ? Record[++I] : 0;
- GlobalValue::GUID CalleeGUID = getGUIDFromValueId(CalleeValueId);
+ GlobalValue::GUID CalleeGUID = getGUIDFromValueId(CalleeValueId).first;
FS->addCallGraphEdge(CalleeGUID,
CalleeInfo(CallsiteCount, ProfileCount));
}
@@ -6156,6 +6183,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
uint64_t AliaseeSummaryOffset = Record[2];
std::unique_ptr<AliasSummary> AS =
llvm::make_unique<AliasSummary>(getDecodedLinkage(RawLinkage));
+ LastSeenSummary = AS.get();
AS->setModulePath(ModuleIdMap[ModuleId]);
auto *AliaseeInfo = getInfoFromSummaryOffset(AliaseeSummaryOffset);
@@ -6175,10 +6203,11 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
uint64_t RawLinkage = Record[1];
std::unique_ptr<GlobalVarSummary> FS =
llvm::make_unique<GlobalVarSummary>(getDecodedLinkage(RawLinkage));
+ LastSeenSummary = FS.get();
FS->setModulePath(ModuleIdMap[ModuleId]);
for (unsigned I = 2, E = Record.size(); I != E; ++I) {
unsigned RefValueId = Record[I];
- GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId);
+ GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
FS->addRefEdge(RefGUID);
}
auto *Info = getInfoFromSummaryOffset(CurRecordBit);
@@ -6187,6 +6216,15 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
Combined = true;
break;
}
+ // FS_COMBINED_ORIGINAL_NAME: [original_name]
+ case bitc::FS_COMBINED_ORIGINAL_NAME: {
+ uint64_t OriginalName = Record[0];
+ if (!LastSeenSummary)
+ return error("Name attachment that does not follow a combined record");
+ LastSeenSummary->setOriginalName(OriginalName);
+ // Reset the LastSeenSummary
+ LastSeenSummary = nullptr;
+ }
}
}
llvm_unreachable("Exit infinite loop");
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 3be4fe03d51..302629b9176 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -3211,6 +3211,17 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
DenseMap<const GlobalValueSummary *, uint64_t> SummaryToOffsetMap;
SmallVector<uint64_t, 64> NameVals;
+
+ // For local linkage, we also emit the original name separately
+ // immediately after the record.
+ auto MaybeEmitOriginalName = [&](GlobalValueSummary &S) {
+ if (!GlobalValue::isLocalLinkage(S.linkage()))
+ return;
+ NameVals.push_back(S.getOriginalName());
+ Stream.EmitRecord(bitc::FS_COMBINED_ORIGINAL_NAME, NameVals);
+ NameVals.clear();
+ };
+
for (const auto &FII : Index) {
for (auto &FI : FII.second) {
GlobalValueSummary *S = FI->summary();
@@ -3241,6 +3252,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
FSModRefsAbbrev);
NameVals.clear();
+ MaybeEmitOriginalName(*S);
continue;
}
@@ -3288,6 +3300,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
// Emit the finished record.
Stream.EmitRecord(Code, NameVals, FSAbbrev);
NameVals.clear();
+ MaybeEmitOriginalName(*S);
}
}
@@ -3307,6 +3320,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
// Emit the finished record.
Stream.EmitRecord(bitc::FS_COMBINED_ALIAS, NameVals, FSAliasAbbrev);
NameVals.clear();
+ MaybeEmitOriginalName(*AS);
}
Stream.ExitBlock();
diff --git a/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll b/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll
new file mode 100644
index 00000000000..431ce367e9b
--- /dev/null
+++ b/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll
@@ -0,0 +1,24 @@
+; Test to check the callgraph in summary
+; RUN: opt -module-summary %s -o %t.o
+; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t.o
+; RUN: llvm-bcanalyzer -dump %t.index.bc | FileCheck %s --check-prefix=COMBINED
+
+; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
+; COMBINED-NEXT: <COMBINED
+; COMBINED-NEXT: <COMBINED_ORIGINAL_NAME op0=6699318081062747564/>
+; COMBINED-NEXT: <COMBINED_GLOBALVAR_INIT_REFS
+; COMBINED-NEXT: <COMBINED_ORIGINAL_NAME op0=-2012135647395072713/>
+; COMBINED-NEXT: <COMBINED_ALIAS
+; COMBINED-NEXT: <COMBINED_ORIGINAL_NAME op0=-4170563161550796836/>
+; COMBINED-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
+
+; ModuleID = 'thinlto-function-summary-callgraph.ll'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@bar = internal global i32 0
+@fooalias = internal alias void (...), bitcast (void ()* @foo to void (...)*)
+
+define internal void @foo() {
+ ret void
+}
diff --git a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 2ac035bcdf8..0ce83c72f24 100644
--- a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -308,6 +308,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS)
STRINGIFY_CODE(FS, ALIAS)
STRINGIFY_CODE(FS, COMBINED_ALIAS)
+ STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME)
}
case bitc::METADATA_ATTACHMENT_ID:
switch(CodeID) {
OpenPOWER on IntegriCloud