llvm.org GIT mirror llvm / ea3f918
IR: Function summary representation for type tests. Each function summary has an attached list of type identifier GUIDs. The idea is that during the regular LTO phase we would match these GUIDs to type identifiers defined by the regular LTO module and store the resolutions in a top-level "type identifier summary" (which will be implemented separately). Differential Revision: https://reviews.llvm.org/D27967 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290280 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 2 years ago
8 changed file(s) with 102 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
212212 FS_COMBINED_ORIGINAL_NAME = 9,
213213 // VERSION of the summary, bumped when adding flags for instance.
214214 FS_VERSION = 10,
215 // The list of llvm.type.test type identifiers used by the following function.
216 FS_TYPE_TESTS = 11,
215217 };
216218
217219 enum MetadataCodes {
283283 /// List of call edge pairs from this function.
284284 std::vector CallGraphEdgeList;
285285
286 /// List of type identifiers used by this function, represented as GUIDs.
287 std::vector TypeIdList;
288
286289 public:
287290 /// Summary constructors.
288291 FunctionSummary(GVFlags Flags, unsigned NumInsts, std::vector Refs,
289 std::vector CGEdges)
292 std::vector CGEdges,
293 std::vector TypeIds)
290294 : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
291 InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)) {}
295 InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)),
296 TypeIdList(std::move(TypeIds)) {}
292297
293298 /// Check if this is a function summary.
294299 static bool classof(const GlobalValueSummary *GVS) {
300305
301306 /// Return the list of pairs.
302307 ArrayRef calls() const { return CallGraphEdgeList; }
308
309 /// Returns the list of type identifiers used by this function.
310 ArrayRef type_tests() const { return TypeIdList; }
303311 };
304312
305313 /// \brief Global variable summary information to aid decisions and
2121 #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
2222 #include "llvm/Analysis/LoopInfo.h"
2323 #include "llvm/Analysis/ProfileSummaryInfo.h"
24 #include "llvm/Analysis/TypeMetadataUtils.h"
2425 #include "llvm/IR/CallSite.h"
2526 #include "llvm/IR/Dominators.h"
2627 #include "llvm/IR/InstIterator.h"
9192 // counts for all static calls to a given callee.
9293 MapVector CallGraphEdges;
9394 SetVector RefEdges;
95 SetVector TypeTests;
9496 ICallPromotionAnalysis ICallAnalysis;
9597
9698 bool HasInlineAsmMaybeReferencingInternal = false;
122124 assert(!CalledFunction && "Expected null called function in callsite for alias");
123125 CalledFunction = dyn_cast(GA->getBaseObject());
124126 }
125 // Check if this is a direct call to a known function.
127 // Check if this is a direct call to a known function or a known
128 // intrinsic, or an indirect call with profile data.
126129 if (CalledFunction) {
127 // Skip intrinsics.
128 if (CalledFunction->isIntrinsic())
129 continue;
130 if (CalledFunction->isIntrinsic()) {
131 if (CalledFunction->getIntrinsicID() != Intrinsic::type_test)
132 continue;
133 // Produce a summary from type.test intrinsics. We only summarize
134 // type.test intrinsics that are used other than by an llvm.assume
135 // intrinsic. Intrinsics that are assumed are relevant only to the
136 // devirtualization pass, not the type test lowering pass.
137 bool HasNonAssumeUses = llvm::any_of(CI->uses(), [](const Use &CIU) {
138 auto *AssumeCI = dyn_cast(CIU.getUser());
139 if (!AssumeCI)
140 return true;
141 Function *F = AssumeCI->getCalledFunction();
142 return !F || F->getIntrinsicID() != Intrinsic::assume;
143 });
144 if (HasNonAssumeUses) {
145 auto *TypeMDVal = cast(CI->getArgOperand(1));
146 if (auto *TypeId = dyn_cast(TypeMDVal->getMetadata()))
147 TypeTests.insert(GlobalValue::getGUID(TypeId->getString()));
148 }
149 }
130150 // We should have named any anonymous globals
131151 assert(CalledFunction->hasName());
132152 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None;
159179
160180 GlobalValueSummary::GVFlags Flags(F);
161181 auto FuncSummary = llvm::make_unique(
162 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector());
182 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
183 TypeTests.takeVector());
163184 if (HasInlineAsmMaybeReferencingInternal)
164185 FuncSummary->setHasInlineAsmMaybeReferencingInternal();
165186 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
279300 std::unique_ptr Summary =
280301 llvm::make_unique(
281302 GVFlags, 0, ArrayRef{},
282 ArrayRef{});
303 ArrayRef{},
304 ArrayRef{});
283305 Summary->setNoRename();
284306 Index.addGlobalValueSummary(Name, std::move(Summary));
285307 } else {
48464846 // "OriginalName" attachement.
48474847 GlobalValueSummary *LastSeenSummary = nullptr;
48484848 bool Combined = false;
4849 std::vector PendingTypeTests;
48494850
48504851 while (true) {
48514852 BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
49114912 ArrayRef(Record).slice(CallGraphEdgeStartIndex),
49124913 IsOldProfileFormat, HasProfile);
49134914 auto FS = llvm::make_unique(
4914 Flags, InstCount, std::move(Refs), std::move(Calls));
4915 Flags, InstCount, std::move(Refs), std::move(Calls),
4916 std::move(PendingTypeTests));
49154917 auto GUID = getGUIDFromValueId(ValueID);
49164918 FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first());
49174919 FS->setOriginalName(GUID.second);
49844986 IsOldProfileFormat, HasProfile);
49854987 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
49864988 auto FS = llvm::make_unique(
4987 Flags, InstCount, std::move(Refs), std::move(Edges));
4989 Flags, InstCount, std::move(Refs), std::move(Edges),
4990 std::move(PendingTypeTests));
49884991 LastSeenSummary = FS.get();
49894992 FS->setModulePath(ModuleIdMap[ModuleId]);
49904993 TheIndex.addGlobalValueSummary(GUID, std::move(FS));
50405043 LastSeenSummary->setOriginalName(OriginalName);
50415044 // Reset the LastSeenSummary
50425045 LastSeenSummary = nullptr;
5046 break;
5047 }
5048 case bitc::FS_TYPE_TESTS: {
5049 assert(PendingTypeTests.empty());
5050 PendingTypeTests.insert(PendingTypeTests.end(), Record.begin(),
5051 Record.end());
5052 break;
50435053 }
50445054 }
50455055 }
32853285 NameVals.push_back(ValueID);
32863286
32873287 FunctionSummary *FS = cast(Summary);
3288 if (!FS->type_tests().empty())
3289 Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
3290
32883291 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
32893292 NameVals.push_back(FS->instCount());
32903293 NameVals.push_back(FS->refs().size());
35433546 }
35443547
35453548 auto *FS = cast(S);
3549 if (!FS->type_tests().empty())
3550 Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
3551
35463552 NameVals.push_back(ValueId);
35473553 NameVals.push_back(Index.getModuleId(FS->modulePath()));
35483554 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
0 ; RUN: opt -module-summary %s -o %t.o
1 ; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
2 ; RUN: llvm-lto -thinlto -o %t2 %t.o
3 ; RUN: llvm-bcanalyzer -dump %t2.thinlto.bc | FileCheck --check-prefix=COMBINED %s
4
5 ; COMBINED:
6 ; COMBINED:
7 ; COMBINED:
8
9 ; CHECK:
10 define i1 @f() {
11 %p = call i1 @llvm.type.test(i8* null, metadata !"foo")
12 ret i1 %p
13 }
14
15 ; CHECK:
16 define i1 @g() {
17 %p = call i1 @llvm.type.test(i8* null, metadata !"foo")
18 %q = call i1 @llvm.type.test(i8* null, metadata !"bar")
19 %pq = and i1 %p, %q
20 ret i1 %pq
21 }
22
23 ; CHECK:
24 define i1 @h() {
25 %p = call i1 @llvm.type.test(i8* null, metadata !"bar")
26 ret i1 %p
27 }
28
29 declare i1 @llvm.type.test(i8*, metadata) nounwind readnone
0 ; RUN: opt -module-summary %s -o %t.o
1 ; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
2
3 ; CHECK-NOT:
4 define void @f() {
5 %p = call i1 @llvm.type.test(i8* null, metadata !"foo")
6 %q = call i1 @llvm.type.test(i8* null, metadata !"bar")
7 call void @llvm.assume(i1 %q)
8 ret void
9 }
10
11 declare i1 @llvm.type.test(i8*, metadata) nounwind readnone
12 declare void @llvm.assume(i1)
310310 STRINGIFY_CODE(FS, COMBINED_ALIAS)
311311 STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME)
312312 STRINGIFY_CODE(FS, VERSION)
313 STRINGIFY_CODE(FS, TYPE_TESTS)
313314 }
314315 case bitc::METADATA_ATTACHMENT_ID:
315316 switch(CodeID) {