summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/AsmWriter.cpp
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2018-09-25 20:14:40 +0000
committerTeresa Johnson <tejohnson@google.com>2018-09-25 20:14:40 +0000
commit7fb39dfa7c4d9997d967d6daaae2d65cfa7af2ef (patch)
tree2491be2092d87ffe06ad5c448f8ba63e4c076d94 /llvm/lib/IR/AsmWriter.cpp
parentd2aab83fa6ff3b5b3de7212456a32eb54dce7354 (diff)
downloadbcm5719-llvm-7fb39dfa7c4d9997d967d6daaae2d65cfa7af2ef.tar.gz
bcm5719-llvm-7fb39dfa7c4d9997d967d6daaae2d65cfa7af2ef.zip
[ThinLTO] Efficiency fix for writing type id records in per-module indexes
Summary: In D49565/r337503, the type id record writing was fixed so that only referenced type ids were emitted into each per-module index for ThinLTO distributed builds. However, this still left an efficiency issue: each per-module index checked all type ids for membership in the referenced set, yielding O(M*N) performance (M indexes and N type ids). Change the TypeIdMap in the summary to be indexed by GUID, to facilitate correlating with type identifier GUIDs referenced in the function summary TypeIdInfo structures. This allowed simplifying other places where a map from type id GUID to type id map entry was previously being used to aid this correlation. Also fix AsmWriter code to handle the rare case of type id GUID collision. For a large internal application, this reduced the thin link time by almost 15%. Reviewers: pcc, vitalybuka Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D51330 llvm-svn: 343021
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp82
1 files changed, 62 insertions, 20 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 536dbe064fc..387154ecfe5 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -705,6 +705,10 @@ private:
DenseMap<GlobalValue::GUID, unsigned> GUIDMap;
unsigned GUIDNext = 0;
+ /// TypeIdMap - The slot map for type ids used in the summary index.
+ StringMap<unsigned> TypeIdMap;
+ unsigned TypeIdNext = 0;
+
public:
/// Construct from a module.
///
@@ -736,6 +740,7 @@ public:
int getAttributeGroupSlot(AttributeSet AS);
int getModulePathSlot(StringRef Path);
int getGUIDSlot(GlobalValue::GUID GUID);
+ int getTypeIdSlot(StringRef Id);
/// If you'd like to deal with a function instead of just a module, use
/// this method to get its data into the SlotTracker.
@@ -790,6 +795,7 @@ private:
inline void CreateModulePathSlot(StringRef Path);
void CreateGUIDSlot(GlobalValue::GUID GUID);
+ void CreateTypeIdSlot(StringRef Id);
/// Add all of the module level global variables (and their initializers)
/// and function declarations, but not the contents of those functions.
@@ -1026,8 +1032,12 @@ void SlotTracker::processIndex() {
for (auto &GlobalList : *TheIndex)
CreateGUIDSlot(GlobalList.first);
- for (auto &TId : TheIndex->typeIds())
- CreateGUIDSlot(GlobalValue::getGUID(TId.first));
+ // Start numbering the TypeIds after the GUIDs.
+ TypeIdNext = GUIDNext;
+
+ for (auto TidIter = TheIndex->typeIds().begin();
+ TidIter != TheIndex->typeIds().end(); TidIter++)
+ CreateTypeIdSlot(TidIter->second.first);
ST_DEBUG("end processIndex!\n");
}
@@ -1133,6 +1143,15 @@ int SlotTracker::getGUIDSlot(GlobalValue::GUID GUID) {
return I == GUIDMap.end() ? -1 : (int)I->second;
}
+int SlotTracker::getTypeIdSlot(StringRef Id) {
+ // Check for uninitialized state and do lazy initialization.
+ initializeIndexIfNeeded();
+
+ // Find the TypeId string in the map
+ auto I = TypeIdMap.find(Id);
+ return I == TypeIdMap.end() ? -1 : (int)I->second;
+}
+
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
assert(V && "Can't insert a null Value into SlotTracker!");
@@ -1203,6 +1222,11 @@ void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
GUIDMap[GUID] = GUIDNext++;
}
+/// Create a new slot for the specified Id
+void SlotTracker::CreateTypeIdSlot(StringRef Id) {
+ TypeIdMap[Id] = TypeIdNext++;
+}
+
//===----------------------------------------------------------------------===//
// AsmWriter Implementation
//===----------------------------------------------------------------------===//
@@ -2656,12 +2680,12 @@ void AssemblyWriter::printModuleSummaryIndex() {
}
// Print the TypeIdMap entries.
- for (auto &TId : TheIndex->typeIds()) {
- auto GUID = GlobalValue::getGUID(TId.first);
- Out << "^" << Machine.getGUIDSlot(GUID) << " = typeid: (name: \""
- << TId.first << "\"";
- printTypeIdSummary(TId.second);
- Out << ") ; guid = " << GUID << "\n";
+ for (auto TidIter = TheIndex->typeIds().begin();
+ TidIter != TheIndex->typeIds().end(); TidIter++) {
+ Out << "^" << Machine.getTypeIdSlot(TidIter->second.first)
+ << " = typeid: (name: \"" << TidIter->second.first << "\"";
+ printTypeIdSummary(TidIter->second.second);
+ Out << ") ; guid = " << TidIter->first << "\n";
}
}
@@ -2894,12 +2918,19 @@ void AssemblyWriter::printTypeIdInfo(
Out << "typeTests: (";
FieldSeparator FS;
for (auto &GUID : TIDInfo.TypeTests) {
- Out << FS;
- auto Slot = Machine.getGUIDSlot(GUID);
- if (Slot != -1)
- Out << "^" << Slot;
- else
+ auto TidIter = TheIndex->typeIds().equal_range(GUID);
+ if (TidIter.first == TidIter.second) {
+ Out << FS;
Out << GUID;
+ continue;
+ }
+ // Print all type id that correspond to this GUID.
+ for (auto It = TidIter.first; It != TidIter.second; ++It) {
+ Out << FS;
+ auto Slot = Machine.getTypeIdSlot(It->second.first);
+ assert(Slot != -1);
+ Out << "^" << Slot;
+ }
}
Out << ")";
}
@@ -2925,14 +2956,25 @@ void AssemblyWriter::printTypeIdInfo(
}
void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
- Out << "vFuncId: (";
- auto Slot = Machine.getGUIDSlot(VFId.GUID);
- if (Slot != -1)
- Out << "^" << Slot;
- else
+ auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID);
+ if (TidIter.first == TidIter.second) {
+ Out << "vFuncId: (";
Out << "guid: " << VFId.GUID;
- Out << ", offset: " << VFId.Offset;
- Out << ")";
+ Out << ", offset: " << VFId.Offset;
+ Out << ")";
+ return;
+ }
+ // Print all type id that correspond to this GUID.
+ FieldSeparator FS;
+ for (auto It = TidIter.first; It != TidIter.second; ++It) {
+ Out << FS;
+ Out << "vFuncId: (";
+ auto Slot = Machine.getTypeIdSlot(It->second.first);
+ assert(Slot != -1);
+ Out << "^" << Slot;
+ Out << ", offset: " << VFId.Offset;
+ Out << ")";
+ }
}
void AssemblyWriter::printNonConstVCalls(
OpenPOWER on IntegriCloud