From 7fb39dfa7c4d9997d967d6daaae2d65cfa7af2ef Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Tue, 25 Sep 2018 20:14:40 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/IR/ModuleSummaryIndex.h | 38 ++++++--- llvm/include/llvm/IR/ModuleSummaryIndexYAML.h | 13 ++- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 13 +-- llvm/lib/IR/AsmWriter.cpp | 82 ++++++++++++++----- llvm/lib/LTO/LTO.cpp | 36 ++------ llvm/test/Assembler/thinlto-summary.ll | 12 +-- .../WholeProgramDevirt/branch-funnel.ll | 30 +++---- .../WholeProgramDevirt/export-single-impl.ll | 26 +++--- 8 files changed, 149 insertions(+), 101 deletions(-) diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h index 9cf8c751e6c3..778907b05eb4 100644 --- a/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h @@ -23,6 +23,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Module.h" #include "llvm/Support/Allocator.h" @@ -753,6 +754,11 @@ using ModulePathStringTableTy = StringMap>; /// a particular module, and provide efficient access to their summary. using GVSummaryMapTy = DenseMap; +/// Map of a type GUID to type id string and summary (multimap used +/// in case of GUID conflicts). +using TypeIdSummaryMapTy = + std::multimap>; + /// Class to hold module path string table and global value map, /// and encapsulate methods for operating on them. class ModuleSummaryIndex { @@ -764,9 +770,9 @@ private: /// Holds strings for combined index, mapping to the corresponding module ID. ModulePathStringTableTy ModulePathStringTable; - /// Mapping from type identifiers to summary information for that type - /// identifier. - std::map TypeIdMap; + /// Mapping from type identifier GUIDs to type identifier and its summary + /// information. + TypeIdSummaryMapTy TypeIdMap; /// Mapping from original ID to GUID. If original ID can map to multiple /// GUIDs, it will be mapped to 0. @@ -1079,23 +1085,29 @@ public: return ModulePathStringTable.count(M.getModuleIdentifier()); } - const std::map &typeIds() const { - return TypeIdMap; - } + const TypeIdSummaryMapTy &typeIds() const { return TypeIdMap; } - /// This accessor should only be used when exporting because it can mutate the - /// map. + /// Return an existing or new TypeIdSummary entry for \p TypeId. + /// This accessor can mutate the map and therefore should not be used in + /// the ThinLTO backends. TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) { - return TypeIdMap[TypeId]; + auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId)); + for (auto It = TidIter.first; It != TidIter.second; ++It) + if (It->second.first == TypeId) + return It->second.second; + auto It = TypeIdMap.insert( + {GlobalValue::getGUID(TypeId), {TypeId, TypeIdSummary()}}); + return It->second.second; } /// This returns either a pointer to the type id summary (if present in the /// summary map) or null (if not present). This may be used when importing. const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const { - auto I = TypeIdMap.find(TypeId); - if (I == TypeIdMap.end()) - return nullptr; - return &I->second; + auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId)); + for (auto It = TidIter.first; It != TidIter.second; ++It) + if (It->second.first == TypeId) + return &It->second.second; + return nullptr; } /// Collect for the given module the list of functions it defines diff --git a/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h b/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h index 1b339ab32cf1..56f56b4b8c2e 100644 --- a/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h +++ b/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -195,7 +195,6 @@ template <> struct MappingTraits { } // End yaml namespace } // End llvm namespace -LLVM_YAML_IS_STRING_MAP(TypeIdSummary) LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) namespace llvm { @@ -258,6 +257,18 @@ template <> struct CustomMappingTraits { } }; +template <> struct CustomMappingTraits { + static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) { + TypeIdSummary TId; + io.mapRequired(Key.str().c_str(), TId); + V.insert({GlobalValue::getGUID(Key), {Key, TId}}); + } + static void output(IO &io, TypeIdSummaryMapTy &V) { + for (auto TidIter = V.begin(); TidIter != V.end(); TidIter++) + io.mapRequired(TidIter->second.first.c_str(), TidIter->second.second); + } +}; + template <> struct MappingTraits { static void mapping(IO &io, ModuleSummaryIndex& index) { io.mapOptional("GlobalValueMap", index.GlobalValueMap); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index b8444bc86d7e..0d23bcaab566 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3903,12 +3903,13 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { NameVals.clear(); } - if (!Index.typeIds().empty()) { - for (auto &S : Index.typeIds()) { - // Skip if not referenced in any GV summary within this index file. - if (!ReferencedTypeIds.count(GlobalValue::getGUID(S.first))) - continue; - writeTypeIdSummaryRecord(NameVals, StrtabBuilder, S.first, S.second); + // Walk the GUIDs that were referenced, and write the + // corresponding type id records. + for (auto &T : ReferencedTypeIds) { + auto TidIter = Index.typeIds().equal_range(T); + for (auto It = TidIter.first; It != TidIter.second; ++It) { + writeTypeIdSummaryRecord(NameVals, StrtabBuilder, It->second.first, + It->second.second); Stream.EmitRecord(bitc::FS_TYPE_ID, NameVals); NameVals.clear(); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 536dbe064fc9..387154ecfe53 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -705,6 +705,10 @@ private: DenseMap GUIDMap; unsigned GUIDNext = 0; + /// TypeIdMap - The slot map for type ids used in the summary index. + StringMap 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( diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 68d210cb7d73..50d0075a6081 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -56,12 +56,6 @@ static cl::opt DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph")); -// The values are (type identifier, summary) pairs. -typedef DenseMap< - GlobalValue::GUID, - TinyPtrVector *>> - TypeIdSummariesByGuidTy; - // Returns a unique hash for the Module considering the current list of // export/import and other global analysis results. // The hash is produced in \p Key. @@ -71,7 +65,6 @@ static void computeCacheKey( const FunctionImporter::ExportSetTy &ExportList, const std::map &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid, const std::set &CfiFunctionDefs, const std::set &CfiFunctionDecls) { // Compute the unique hash for this entry. @@ -255,10 +248,9 @@ static void computeCacheKey( // Include the hash for all type identifiers used by this module. for (GlobalValue::GUID TId : UsedTypeIds) { - auto SummariesI = TypeIdSummariesByGuid.find(TId); - if (SummariesI != TypeIdSummariesByGuid.end()) - for (auto *Summary : SummariesI->second) - AddTypeIdSummary(Summary->first, Summary->second); + auto TidIter = Index.typeIds().equal_range(TId); + for (auto It = TidIter.first; It != TidIter.second; ++It) + AddTypeIdSummary(It->second.first, It->second.second); } AddUnsigned(UsedCfiDefs.size()); @@ -917,7 +909,6 @@ class InProcessThinBackend : public ThinBackendProc { ThreadPool BackendThreadPool; AddStreamFn AddStream; NativeObjectCache Cache; - TypeIdSummariesByGuidTy TypeIdSummariesByGuid; std::set CfiFunctionDefs; std::set CfiFunctionDecls; @@ -933,12 +924,6 @@ public: : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), BackendThreadPool(ThinLTOParallelismLevel), AddStream(std::move(AddStream)), Cache(std::move(Cache)) { - // Create a mapping from type identifier GUIDs to type identifier summaries. - // This allows backends to use the type identifier GUIDs stored in the - // function summaries to determine which type identifier summaries affect - // each function without needing to compute GUIDs in each backend. - for (auto &TId : CombinedIndex.typeIds()) - TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId); for (auto &Name : CombinedIndex.cfiFunctionDefs()) CfiFunctionDefs.insert( GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name))); @@ -954,8 +939,7 @@ public: const FunctionImporter::ExportSetTy &ExportList, const std::map &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - MapVector &ModuleMap, - const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid) { + MapVector &ModuleMap) { auto RunThinBackend = [&](AddStreamFn AddStream) { LTOLLVMContext BackendContext(Conf); Expected> MOrErr = BM.parseModule(BackendContext); @@ -978,8 +962,8 @@ public: SmallString<40> Key; // The module may be cached, this helps handling it. computeCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList, ExportList, - ResolvedODR, DefinedGlobals, TypeIdSummariesByGuid, - CfiFunctionDefs, CfiFunctionDecls); + ResolvedODR, DefinedGlobals, CfiFunctionDefs, + CfiFunctionDecls); if (AddStreamFn CacheAddStream = Cache(Task, Key)) return RunThinBackend(CacheAddStream); @@ -1003,11 +987,10 @@ public: const std::map &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - MapVector &ModuleMap, - const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid) { + MapVector &ModuleMap) { Error E = runThinLTOBackendThread( AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList, - ResolvedODR, DefinedGlobals, ModuleMap, TypeIdSummariesByGuid); + ResolvedODR, DefinedGlobals, ModuleMap); if (E) { std::unique_lock L(ErrMu); if (Err) @@ -1017,8 +1000,7 @@ public: } }, BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList), - std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap), - std::ref(TypeIdSummariesByGuid)); + std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap)); return Error::success(); } diff --git a/llvm/test/Assembler/thinlto-summary.ll b/llvm/test/Assembler/thinlto-summary.ll index 0149f45a2275..01bf3a8c8101 100644 --- a/llvm/test/Assembler/thinlto-summary.ll +++ b/llvm/test/Assembler/thinlto-summary.ll @@ -54,13 +54,13 @@ ; Test TypeId summaries: -; Test the AllOnes resolution, and all kinds of WholeProgramDevirtResolution -; types, including all optional resolution by argument kinds. -^24 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi")), (offset: 16, wpdRes: (kind: indir, resByArg: (args: (1, 2), byArg: (kind: indir, byte: 2, bit: 3), args: (3), byArg: (kind: uniformRetVal, info: 1), args: (4), byArg: (kind: uniqueRetVal, info: 1), args: (5), byArg: (kind: virtualConstProp))))))) +^24 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; Test TypeId with other optional fields (alignLog2/sizeM1/bitMask/inlineBits) ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4))) +; Test the AllOnes resolution, and all kinds of WholeProgramDevirtResolution +; types, including all optional resolution by argument kinds. +^26 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi")), (offset: 16, wpdRes: (kind: indir, resByArg: (args: (1, 2), byArg: (kind: indir, byte: 2, bit: 3), args: (3), byArg: (kind: uniformRetVal, info: 1), args: (4), byArg: (kind: uniqueRetVal, info: 1), args: (5), byArg: (kind: virtualConstProp))))))) ; Test the other kinds of type test resoultions -^26 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ^27 = typeid: (name: "_ZTS1D", summary: (typeTestRes: (kind: byteArray, sizeM1BitWidth: 0))) ^28 = typeid: (name: "_ZTS1E", summary: (typeTestRes: (kind: unsat, sizeM1BitWidth: 0))) @@ -89,8 +89,8 @@ ; CHECK: ^21 = gv: (guid: 20, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadVCalls: (vFuncId: (^25, offset: 16)))))) ; CHECK: ^22 = gv: (guid: 21, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 15, typeIdInfo: (typeTestAssumeConstVCalls: ((vFuncId: (^27, offset: 16), args: (42)), (vFuncId: (^27, offset: 24))))))) ; CHECK: ^23 = gv: (guid: 22, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadConstVCalls: ((vFuncId: (^28, offset: 16), args: (42))))))) -; CHECK: ^24 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi")), (offset: 16, wpdRes: (kind: indir, resByArg: (args: (1, 2), byArg: (kind: indir, byte: 2, bit: 3), args: (3), byArg: (kind: uniformRetVal, info: 1), args: (4), byArg: (kind: uniqueRetVal, info: 1), args: (5), byArg: (kind: virtualConstProp))))))) ; guid = 7004155349499253778 +; CHECK: ^24 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 1884921850105019584 ; CHECK: ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4))) ; guid = 6203814149063363976 -; CHECK: ^26 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 1884921850105019584 +; CHECK: ^26 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi")), (offset: 16, wpdRes: (kind: indir, resByArg: (args: (1, 2), byArg: (kind: indir, byte: 2, bit: 3), args: (3), byArg: (kind: uniformRetVal, info: 1), args: (4), byArg: (kind: uniqueRetVal, info: 1), args: (5), byArg: (kind: virtualConstProp))))))) ; guid = 7004155349499253778 ; CHECK: ^27 = typeid: (name: "_ZTS1D", summary: (typeTestRes: (kind: byteArray, sizeM1BitWidth: 0))) ; guid = 9614786172484273522 ; CHECK: ^28 = typeid: (name: "_ZTS1E", summary: (typeTestRes: (kind: unsat, sizeM1BitWidth: 0))) ; guid = 17437243864166745132 diff --git a/llvm/test/Transforms/WholeProgramDevirt/branch-funnel.ll b/llvm/test/Transforms/WholeProgramDevirt/branch-funnel.ll index cea82050f992..49d9caaf71ec 100644 --- a/llvm/test/Transforms/WholeProgramDevirt/branch-funnel.ll +++ b/llvm/test/Transforms/WholeProgramDevirt/branch-funnel.ll @@ -8,7 +8,7 @@ ; RUN: FileCheck --check-prefix=SUMMARY %s < %t ; SUMMARY: TypeIdMap: -; SUMMARY-NEXT: typeid1: +; SUMMARY-NEXT: typeid3: ; SUMMARY-NEXT: TTRes: ; SUMMARY-NEXT: Kind: Unsat ; SUMMARY-NEXT: SizeM1BitWidth: 0 @@ -21,7 +21,20 @@ ; SUMMARY-NEXT: Kind: BranchFunnel ; SUMMARY-NEXT: SingleImplName: '' ; SUMMARY-NEXT: ResByArg: -; SUMMARY-NEXT: typeid2: +; SUMMARY-NEXT: typeid1: +; SUMMARY-NEXT: TTRes: +; SUMMARY-NEXT: Kind: Unsat +; SUMMARY-NEXT: SizeM1BitWidth: 0 +; SUMMARY-NEXT: AlignLog2: 0 +; SUMMARY-NEXT: SizeM1: 0 +; SUMMARY-NEXT: BitMask: 0 +; SUMMARY-NEXT: InlineBits: 0 +; SUMMARY-NEXT: WPDRes: +; SUMMARY-NEXT: 0: +; SUMMARY-NEXT: Kind: BranchFunnel +; SUMMARY-NEXT: SingleImplName: '' +; SUMMARY-NEXT: ResByArg: +; SUMMARY-NEXT: typeid2: ; SUMMARY-NEXT: TTRes: ; SUMMARY-NEXT: Kind: Unsat ; SUMMARY-NEXT: SizeM1BitWidth: 0 @@ -34,19 +47,6 @@ ; SUMMARY-NEXT: Kind: Indir ; SUMMARY-NEXT: SingleImplName: '' ; SUMMARY-NEXT: ResByArg: -; SUMMARY-NEXT: typeid3: -; SUMMARY-NEXT: TTRes: -; SUMMARY-NEXT: Kind: Unsat -; SUMMARY-NEXT: SizeM1BitWidth: 0 -; SUMMARY-NEXT: AlignLog2: 0 -; SUMMARY-NEXT: SizeM1: 0 -; SUMMARY-NEXT: BitMask: 0 -; SUMMARY-NEXT: InlineBits: 0 -; SUMMARY-NEXT: WPDRes: -; SUMMARY-NEXT: 0: -; SUMMARY-NEXT: Kind: BranchFunnel -; SUMMARY-NEXT: SingleImplName: '' -; SUMMARY-NEXT: ResByArg: target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll b/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll index 9b7cf8432f74..e03933ccb26d 100644 --- a/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll +++ b/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll @@ -2,6 +2,19 @@ ; RUN: FileCheck --check-prefix=SUMMARY %s < %t ; SUMMARY: TypeIdMap: +; SUMMARY-NEXT: typeid3: +; SUMMARY-NEXT: TTRes: +; SUMMARY-NEXT: Kind: Unsat +; SUMMARY-NEXT: SizeM1BitWidth: 0 +; SUMMARY-NEXT: AlignLog2: 0 +; SUMMARY-NEXT: SizeM1: 0 +; SUMMARY-NEXT: BitMask: 0 +; SUMMARY-NEXT: InlineBits: 0 +; SUMMARY-NEXT: WPDRes: +; SUMMARY-NEXT: 0: +; SUMMARY-NEXT: Kind: SingleImpl +; SUMMARY-NEXT: SingleImplName: 'vf3$merged' +; SUMMARY-NEXT: ResByArg: ; SUMMARY-NEXT: typeid1: ; SUMMARY-NEXT: TTRes: ; SUMMARY-NEXT: Kind: Unsat @@ -28,19 +41,6 @@ ; SUMMARY-NEXT: Kind: SingleImpl ; SUMMARY-NEXT: SingleImplName: vf2 ; SUMMARY-NEXT: ResByArg: -; SUMMARY-NEXT: typeid3: -; SUMMARY-NEXT: TTRes: -; SUMMARY-NEXT: Kind: Unsat -; SUMMARY-NEXT: SizeM1BitWidth: 0 -; SUMMARY-NEXT: AlignLog2: 0 -; SUMMARY-NEXT: SizeM1: 0 -; SUMMARY-NEXT: BitMask: 0 -; SUMMARY-NEXT: InlineBits: 0 -; SUMMARY-NEXT: WPDRes: -; SUMMARY-NEXT: 0: -; SUMMARY-NEXT: Kind: SingleImpl -; SUMMARY-NEXT: SingleImplName: 'vf3$merged' -; SUMMARY-NEXT: ResByArg: ; SUMMARY-NEXT: typeid4: ; SUMMARY-NEXT: TTRes: ; SUMMARY-NEXT: Kind: Unsat