llvm.org GIT mirror llvm / 0d4dfd2
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343021 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 11 months ago
8 changed file(s) with 150 addition(s) and 102 deletion(s). Raw diff Collapse all Expand all
2222 #include "llvm/ADT/StringExtras.h"
2323 #include "llvm/ADT/StringMap.h"
2424 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/TinyPtrVector.h"
2526 #include "llvm/IR/GlobalValue.h"
2627 #include "llvm/IR/Module.h"
2728 #include "llvm/Support/Allocator.h"
752753 /// a particular module, and provide efficient access to their summary.
753754 using GVSummaryMapTy = DenseMap;
754755
756 /// Map of a type GUID to type id string and summary (multimap used
757 /// in case of GUID conflicts).
758 using TypeIdSummaryMapTy =
759 std::multimap>;
760
755761 /// Class to hold module path string table and global value map,
756762 /// and encapsulate methods for operating on them.
757763 class ModuleSummaryIndex {
763769 /// Holds strings for combined index, mapping to the corresponding module ID.
764770 ModulePathStringTableTy ModulePathStringTable;
765771
766 /// Mapping from type identifiers to summary information for that type
767 /// identifier.
768 std::map TypeIdMap;
772 /// Mapping from type identifier GUIDs to type identifier and its summary
773 /// information.
774 TypeIdSummaryMapTy TypeIdMap;
769775
770776 /// Mapping from original ID to GUID. If original ID can map to multiple
771777 /// GUIDs, it will be mapped to 0.
10781084 return ModulePathStringTable.count(M.getModuleIdentifier());
10791085 }
10801086
1081 const std::map &typeIds() const {
1082 return TypeIdMap;
1083 }
1084
1085 /// This accessor should only be used when exporting because it can mutate the
1086 /// map.
1087 const TypeIdSummaryMapTy &typeIds() const { return TypeIdMap; }
1088
1089 /// Return an existing or new TypeIdSummary entry for \p TypeId.
1090 /// This accessor can mutate the map and therefore should not be used in
1091 /// the ThinLTO backends.
10871092 TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
1088 return TypeIdMap[TypeId];
1093 auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
1094 for (auto It = TidIter.first; It != TidIter.second; ++It)
1095 if (It->second.first == TypeId)
1096 return It->second.second;
1097 auto It = TypeIdMap.insert(
1098 {GlobalValue::getGUID(TypeId), {TypeId, TypeIdSummary()}});
1099 return It->second.second;
10891100 }
10901101
10911102 /// This returns either a pointer to the type id summary (if present in the
10921103 /// summary map) or null (if not present). This may be used when importing.
10931104 const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
1094 auto I = TypeIdMap.find(TypeId);
1095 if (I == TypeIdMap.end())
1096 return nullptr;
1097 return &I->second;
1105 auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
1106 for (auto It = TidIter.first; It != TidIter.second; ++It)
1107 if (It->second.first == TypeId)
1108 return &It->second.second;
1109 return nullptr;
10981110 }
10991111
11001112 /// Collect for the given module the list of functions it defines
194194 } // End yaml namespace
195195 } // End llvm namespace
196196
197 LLVM_YAML_IS_STRING_MAP(TypeIdSummary)
198197 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml)
199198
200199 namespace llvm {
257256 }
258257 };
259258
259 template <> struct CustomMappingTraits {
260 static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) {
261 TypeIdSummary TId;
262 io.mapRequired(Key.str().c_str(), TId);
263 V.insert({GlobalValue::getGUID(Key), {Key, TId}});
264 }
265 static void output(IO &io, TypeIdSummaryMapTy &V) {
266 for (auto TidIter = V.begin(); TidIter != V.end(); TidIter++)
267 io.mapRequired(TidIter->second.first.c_str(), TidIter->second.second);
268 }
269 };
270
260271 template <> struct MappingTraits {
261272 static void mapping(IO &io, ModuleSummaryIndex& index) {
262273 io.mapOptional("GlobalValueMap", index.GlobalValueMap);
39023902 NameVals.clear();
39033903 }
39043904
3905 if (!Index.typeIds().empty()) {
3906 for (auto &S : Index.typeIds()) {
3907 // Skip if not referenced in any GV summary within this index file.
3908 if (!ReferencedTypeIds.count(GlobalValue::getGUID(S.first)))
3909 continue;
3910 writeTypeIdSummaryRecord(NameVals, StrtabBuilder, S.first, S.second);
3905 // Walk the GUIDs that were referenced, and write the
3906 // corresponding type id records.
3907 for (auto &T : ReferencedTypeIds) {
3908 auto TidIter = Index.typeIds().equal_range(T);
3909 for (auto It = TidIter.first; It != TidIter.second; ++It) {
3910 writeTypeIdSummaryRecord(NameVals, StrtabBuilder, It->second.first,
3911 It->second.second);
39113912 Stream.EmitRecord(bitc::FS_TYPE_ID, NameVals);
39123913 NameVals.clear();
39133914 }
704704 DenseMap GUIDMap;
705705 unsigned GUIDNext = 0;
706706
707 /// TypeIdMap - The slot map for type ids used in the summary index.
708 StringMap TypeIdMap;
709 unsigned TypeIdNext = 0;
710
707711 public:
708712 /// Construct from a module.
709713 ///
735739 int getAttributeGroupSlot(AttributeSet AS);
736740 int getModulePathSlot(StringRef Path);
737741 int getGUIDSlot(GlobalValue::GUID GUID);
742 int getTypeIdSlot(StringRef Id);
738743
739744 /// If you'd like to deal with a function instead of just a module, use
740745 /// this method to get its data into the SlotTracker.
789794
790795 inline void CreateModulePathSlot(StringRef Path);
791796 void CreateGUIDSlot(GlobalValue::GUID GUID);
797 void CreateTypeIdSlot(StringRef Id);
792798
793799 /// Add all of the module level global variables (and their initializers)
794800 /// and function declarations, but not the contents of those functions.
10251031 for (auto &GlobalList : *TheIndex)
10261032 CreateGUIDSlot(GlobalList.first);
10271033
1028 for (auto &TId : TheIndex->typeIds())
1029 CreateGUIDSlot(GlobalValue::getGUID(TId.first));
1034 // Start numbering the TypeIds after the GUIDs.
1035 TypeIdNext = GUIDNext;
1036
1037 for (auto TidIter = TheIndex->typeIds().begin();
1038 TidIter != TheIndex->typeIds().end(); TidIter++)
1039 CreateTypeIdSlot(TidIter->second.first);
10301040
10311041 ST_DEBUG("end processIndex!\n");
10321042 }
11321142 return I == GUIDMap.end() ? -1 : (int)I->second;
11331143 }
11341144
1145 int SlotTracker::getTypeIdSlot(StringRef Id) {
1146 // Check for uninitialized state and do lazy initialization.
1147 initializeIndexIfNeeded();
1148
1149 // Find the TypeId string in the map
1150 auto I = TypeIdMap.find(Id);
1151 return I == TypeIdMap.end() ? -1 : (int)I->second;
1152 }
1153
11351154 /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
11361155 void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
11371156 assert(V && "Can't insert a null Value into SlotTracker!");
12001219 /// Create a new slot for the specified GUID
12011220 void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
12021221 GUIDMap[GUID] = GUIDNext++;
1222 }
1223
1224 /// Create a new slot for the specified Id
1225 void SlotTracker::CreateTypeIdSlot(StringRef Id) {
1226 TypeIdMap[Id] = TypeIdNext++;
12031227 }
12041228
12051229 //===----------------------------------------------------------------------===//
26552679 }
26562680
26572681 // Print the TypeIdMap entries.
2658 for (auto &TId : TheIndex->typeIds()) {
2659 auto GUID = GlobalValue::getGUID(TId.first);
2660 Out << "^" << Machine.getGUIDSlot(GUID) << " = typeid: (name: \""
2661 << TId.first << "\"";
2662 printTypeIdSummary(TId.second);
2663 Out << ") ; guid = " << GUID << "\n";
2682 for (auto TidIter = TheIndex->typeIds().begin();
2683 TidIter != TheIndex->typeIds().end(); TidIter++) {
2684 Out << "^" << Machine.getTypeIdSlot(TidIter->second.first)
2685 << " = typeid: (name: \"" << TidIter->second.first << "\"";
2686 printTypeIdSummary(TidIter->second.second);
2687 Out << ") ; guid = " << TidIter->first << "\n";
26642688 }
26652689 }
26662690
28932917 Out << "typeTests: (";
28942918 FieldSeparator FS;
28952919 for (auto &GUID : TIDInfo.TypeTests) {
2896 Out << FS;
2897 auto Slot = Machine.getGUIDSlot(GUID);
2898 if (Slot != -1)
2920 auto TidIter = TheIndex->typeIds().equal_range(GUID);
2921 if (TidIter.first == TidIter.second) {
2922 Out << FS;
2923 Out << GUID;
2924 continue;
2925 }
2926 // Print all type id that correspond to this GUID.
2927 for (auto It = TidIter.first; It != TidIter.second; ++It) {
2928 Out << FS;
2929 auto Slot = Machine.getTypeIdSlot(It->second.first);
2930 assert(Slot != -1);
28992931 Out << "^" << Slot;
2900 else
2901 Out << GUID;
2932 }
29022933 }
29032934 Out << ")";
29042935 }
29242955 }
29252956
29262957 void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
2927 Out << "vFuncId: (";
2928 auto Slot = Machine.getGUIDSlot(VFId.GUID);
2929 if (Slot != -1)
2958 auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID);
2959 if (TidIter.first == TidIter.second) {
2960 Out << "vFuncId: (";
2961 Out << "guid: " << VFId.GUID;
2962 Out << ", offset: " << VFId.Offset;
2963 Out << ")";
2964 return;
2965 }
2966 // Print all type id that correspond to this GUID.
2967 FieldSeparator FS;
2968 for (auto It = TidIter.first; It != TidIter.second; ++It) {
2969 Out << FS;
2970 Out << "vFuncId: (";
2971 auto Slot = Machine.getTypeIdSlot(It->second.first);
2972 assert(Slot != -1);
29302973 Out << "^" << Slot;
2931 else
2932 Out << "guid: " << VFId.GUID;
2933 Out << ", offset: " << VFId.Offset;
2934 Out << ")";
2974 Out << ", offset: " << VFId.Offset;
2975 Out << ")";
2976 }
29352977 }
29362978
29372979 void AssemblyWriter::printNonConstVCalls(
5555 DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden,
5656 cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));
5757
58 // The values are (type identifier, summary) pairs.
59 typedef DenseMap<
60 GlobalValue::GUID,
61 TinyPtrVector *>>
62 TypeIdSummariesByGuidTy;
63
6458 // Returns a unique hash for the Module considering the current list of
6559 // export/import and other global analysis results.
6660 // The hash is produced in \p Key.
7064 const FunctionImporter::ExportSetTy &ExportList,
7165 const std::map &ResolvedODR,
7266 const GVSummaryMapTy &DefinedGlobals,
73 const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid,
7467 const std::set &CfiFunctionDefs,
7568 const std::set &CfiFunctionDecls) {
7669 // Compute the unique hash for this entry.
254247
255248 // Include the hash for all type identifiers used by this module.
256249 for (GlobalValue::GUID TId : UsedTypeIds) {
257 auto SummariesI = TypeIdSummariesByGuid.find(TId);
258 if (SummariesI != TypeIdSummariesByGuid.end())
259 for (auto *Summary : SummariesI->second)
260 AddTypeIdSummary(Summary->first, Summary->second);
250 auto TidIter = Index.typeIds().equal_range(TId);
251 for (auto It = TidIter.first; It != TidIter.second; ++It)
252 AddTypeIdSummary(It->second.first, It->second.second);
261253 }
262254
263255 AddUnsigned(UsedCfiDefs.size());
916908 ThreadPool BackendThreadPool;
917909 AddStreamFn AddStream;
918910 NativeObjectCache Cache;
919 TypeIdSummariesByGuidTy TypeIdSummariesByGuid;
920911 std::set CfiFunctionDefs;
921912 std::set CfiFunctionDecls;
922913
932923 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries),
933924 BackendThreadPool(ThinLTOParallelismLevel),
934925 AddStream(std::move(AddStream)), Cache(std::move(Cache)) {
935 // Create a mapping from type identifier GUIDs to type identifier summaries.
936 // This allows backends to use the type identifier GUIDs stored in the
937 // function summaries to determine which type identifier summaries affect
938 // each function without needing to compute GUIDs in each backend.
939 for (auto &TId : CombinedIndex.typeIds())
940 TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId);
941926 for (auto &Name : CombinedIndex.cfiFunctionDefs())
942927 CfiFunctionDefs.insert(
943928 GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
953938 const FunctionImporter::ExportSetTy &ExportList,
954939 const std::map &ResolvedODR,
955940 const GVSummaryMapTy &DefinedGlobals,
956 MapVector &ModuleMap,
957 const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid) {
941 MapVector &ModuleMap) {
958942 auto RunThinBackend = [&](AddStreamFn AddStream) {
959943 LTOLLVMContext BackendContext(Conf);
960944 Expected> MOrErr = BM.parseModule(BackendContext);
977961 SmallString<40> Key;
978962 // The module may be cached, this helps handling it.
979963 computeCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList, ExportList,
980 ResolvedODR, DefinedGlobals, TypeIdSummariesByGuid,
981 CfiFunctionDefs, CfiFunctionDecls);
964 ResolvedODR, DefinedGlobals, CfiFunctionDefs,
965 CfiFunctionDecls);
982966 if (AddStreamFn CacheAddStream = Cache(Task, Key))
983967 return RunThinBackend(CacheAddStream);
984968
1002986 const std::map
1003987 &ResolvedODR,
1004988 const GVSummaryMapTy &DefinedGlobals,
1005 MapVector &ModuleMap,
1006 const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid) {
989 MapVector &ModuleMap) {
1007990 Error E = runThinLTOBackendThread(
1008991 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1009 ResolvedODR, DefinedGlobals, ModuleMap, TypeIdSummariesByGuid);
992 ResolvedODR, DefinedGlobals, ModuleMap);
1010993 if (E) {
1011994 std::unique_lock L(ErrMu);
1012995 if (Err)
1016999 }
10171000 },
10181001 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1019 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap),
1020 std::ref(TypeIdSummariesByGuid));
1002 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
10211003 return Error::success();
10221004 }
10231005
5353
5454 ; Test TypeId summaries:
5555
56 ^24 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0)))
57 ; Test TypeId with other optional fields (alignLog2/sizeM1/bitMask/inlineBits)
58 ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4)))
5659 ; Test the AllOnes resolution, and all kinds of WholeProgramDevirtResolution
5760 ; types, including all optional resolution by argument kinds.
58 ^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)))))))
59 ; Test TypeId with other optional fields (alignLog2/sizeM1/bitMask/inlineBits)
60 ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4)))
61 ^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)))))))
6162 ; Test the other kinds of type test resoultions
62 ^26 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0)))
6363 ^27 = typeid: (name: "_ZTS1D", summary: (typeTestRes: (kind: byteArray, sizeM1BitWidth: 0)))
6464 ^28 = typeid: (name: "_ZTS1E", summary: (typeTestRes: (kind: unsat, sizeM1BitWidth: 0)))
6565
8888 ; 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))))))
8989 ; 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)))))))
9090 ; 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)))))))
91 ; 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
91 ; CHECK: ^24 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 1884921850105019584
9292 ; CHECK: ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4))) ; guid = 6203814149063363976
93 ; CHECK: ^26 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 1884921850105019584
93 ; 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
9494 ; CHECK: ^27 = typeid: (name: "_ZTS1D", summary: (typeTestRes: (kind: byteArray, sizeM1BitWidth: 0))) ; guid = 9614786172484273522
9595 ; CHECK: ^28 = typeid: (name: "_ZTS1E", summary: (typeTestRes: (kind: unsat, sizeM1BitWidth: 0))) ; guid = 17437243864166745132
77 ; RUN: FileCheck --check-prefix=SUMMARY %s < %t
88
99 ; SUMMARY: TypeIdMap:
10 ; SUMMARY-NEXT: typeid1:
10 ; SUMMARY-NEXT: typeid3:
1111 ; SUMMARY-NEXT: TTRes:
1212 ; SUMMARY-NEXT: Kind: Unsat
1313 ; SUMMARY-NEXT: SizeM1BitWidth: 0
2020 ; SUMMARY-NEXT: Kind: BranchFunnel
2121 ; SUMMARY-NEXT: SingleImplName: ''
2222 ; SUMMARY-NEXT: ResByArg:
23 ; SUMMARY-NEXT: typeid2:
23 ; SUMMARY-NEXT: typeid1:
24 ; SUMMARY-NEXT: TTRes:
25 ; SUMMARY-NEXT: Kind: Unsat
26 ; SUMMARY-NEXT: SizeM1BitWidth: 0
27 ; SUMMARY-NEXT: AlignLog2: 0
28 ; SUMMARY-NEXT: SizeM1: 0
29 ; SUMMARY-NEXT: BitMask: 0
30 ; SUMMARY-NEXT: InlineBits: 0
31 ; SUMMARY-NEXT: WPDRes:
32 ; SUMMARY-NEXT: 0:
33 ; SUMMARY-NEXT: Kind: BranchFunnel
34 ; SUMMARY-NEXT: SingleImplName: ''
35 ; SUMMARY-NEXT: ResByArg:
36 ; SUMMARY-NEXT: typeid2:
2437 ; SUMMARY-NEXT: TTRes:
2538 ; SUMMARY-NEXT: Kind: Unsat
2639 ; SUMMARY-NEXT: SizeM1BitWidth: 0
3144 ; SUMMARY-NEXT: WPDRes:
3245 ; SUMMARY-NEXT: 0:
3346 ; SUMMARY-NEXT: Kind: Indir
34 ; SUMMARY-NEXT: SingleImplName: ''
35 ; SUMMARY-NEXT: ResByArg:
36 ; SUMMARY-NEXT: typeid3:
37 ; SUMMARY-NEXT: TTRes:
38 ; SUMMARY-NEXT: Kind: Unsat
39 ; SUMMARY-NEXT: SizeM1BitWidth: 0
40 ; SUMMARY-NEXT: AlignLog2: 0
41 ; SUMMARY-NEXT: SizeM1: 0
42 ; SUMMARY-NEXT: BitMask: 0
43 ; SUMMARY-NEXT: InlineBits: 0
44 ; SUMMARY-NEXT: WPDRes:
45 ; SUMMARY-NEXT: 0:
46 ; SUMMARY-NEXT: Kind: BranchFunnel
4747 ; SUMMARY-NEXT: SingleImplName: ''
4848 ; SUMMARY-NEXT: ResByArg:
4949
11 ; RUN: FileCheck --check-prefix=SUMMARY %s < %t
22
33 ; SUMMARY: TypeIdMap:
4 ; SUMMARY-NEXT: typeid3:
5 ; SUMMARY-NEXT: TTRes:
6 ; SUMMARY-NEXT: Kind: Unsat
7 ; SUMMARY-NEXT: SizeM1BitWidth: 0
8 ; SUMMARY-NEXT: AlignLog2: 0
9 ; SUMMARY-NEXT: SizeM1: 0
10 ; SUMMARY-NEXT: BitMask: 0
11 ; SUMMARY-NEXT: InlineBits: 0
12 ; SUMMARY-NEXT: WPDRes:
13 ; SUMMARY-NEXT: 0:
14 ; SUMMARY-NEXT: Kind: SingleImpl
15 ; SUMMARY-NEXT: SingleImplName: 'vf3$merged'
16 ; SUMMARY-NEXT: ResByArg:
417 ; SUMMARY-NEXT: typeid1:
518 ; SUMMARY-NEXT: TTRes:
619 ; SUMMARY-NEXT: Kind: Unsat
2639 ; SUMMARY-NEXT: 0:
2740 ; SUMMARY-NEXT: Kind: SingleImpl
2841 ; SUMMARY-NEXT: SingleImplName: vf2
29 ; SUMMARY-NEXT: ResByArg:
30 ; SUMMARY-NEXT: typeid3:
31 ; SUMMARY-NEXT: TTRes:
32 ; SUMMARY-NEXT: Kind: Unsat
33 ; SUMMARY-NEXT: SizeM1BitWidth: 0
34 ; SUMMARY-NEXT: AlignLog2: 0
35 ; SUMMARY-NEXT: SizeM1: 0
36 ; SUMMARY-NEXT: BitMask: 0
37 ; SUMMARY-NEXT: InlineBits: 0
38 ; SUMMARY-NEXT: WPDRes:
39 ; SUMMARY-NEXT: 0:
40 ; SUMMARY-NEXT: Kind: SingleImpl
41 ; SUMMARY-NEXT: SingleImplName: 'vf3$merged'
4242 ; SUMMARY-NEXT: ResByArg:
4343 ; SUMMARY-NEXT: typeid4:
4444 ; SUMMARY-NEXT: TTRes: