LLVM 19.0.0git
ModuleSummaryAnalysis.cpp
Go to the documentation of this file.
1//===- ModuleSummaryAnalysis.cpp - Module summary index builder -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass builds a ModuleSummaryIndex object for the module, to be written
10// to bitcode or LLVM assembly.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/ADT/MapVector.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SetVector.h"
22#include "llvm/ADT/StringRef.h"
32#include "llvm/IR/Attributes.h"
33#include "llvm/IR/BasicBlock.h"
34#include "llvm/IR/Constant.h"
35#include "llvm/IR/Constants.h"
36#include "llvm/IR/Dominators.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GlobalAlias.h"
39#include "llvm/IR/GlobalValue.h"
43#include "llvm/IR/Metadata.h"
44#include "llvm/IR/Module.h"
46#include "llvm/IR/Use.h"
47#include "llvm/IR/User.h"
51#include "llvm/Pass.h"
55#include <algorithm>
56#include <cassert>
57#include <cstdint>
58#include <vector>
59
60using namespace llvm;
61using namespace llvm::memprof;
62
63#define DEBUG_TYPE "module-summary-analysis"
64
65// Option to force edges cold which will block importing when the
66// -import-cold-multiplier is set to 0. Useful for debugging.
67namespace llvm {
70} // namespace llvm
71
73 "force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold),
74 cl::desc("Force all edges in the function summary to cold"),
77 "all-non-critical", "All non-critical edges."),
78 clEnumValN(FunctionSummary::FSHT_All, "all", "All edges.")));
79
81 "module-summary-dot-file", cl::Hidden, cl::value_desc("filename"),
82 cl::desc("File to emit dot graph of new summary into"));
83
85
87
88// Walk through the operands of a given User via worklist iteration and populate
89// the set of GlobalValue references encountered. Invoked either on an
90// Instruction or a GlobalVariable (which walks its initializer).
91// Return true if any of the operands contains blockaddress. This is important
92// to know when computing summary for global var, because if global variable
93// references basic block address we can't import it separately from function
94// containing that basic block. For simplicity we currently don't import such
95// global vars at all. When importing function we aren't interested if any
96// instruction in it takes an address of any basic block, because instruction
97// can only take an address of basic block located in the same function.
98// Set `RefLocalLinkageIFunc` to true if the analyzed value references a
99// local-linkage ifunc.
100static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
101 SetVector<ValueInfo, std::vector<ValueInfo>> &RefEdges,
103 bool &RefLocalLinkageIFunc) {
104 bool HasBlockAddress = false;
106 if (Visited.insert(CurUser).second)
107 Worklist.push_back(CurUser);
108
109 while (!Worklist.empty()) {
110 const User *U = Worklist.pop_back_val();
111 const auto *CB = dyn_cast<CallBase>(U);
112
113 for (const auto &OI : U->operands()) {
114 const User *Operand = dyn_cast<User>(OI);
115 if (!Operand)
116 continue;
117 if (isa<BlockAddress>(Operand)) {
118 HasBlockAddress = true;
119 continue;
120 }
121 if (auto *GV = dyn_cast<GlobalValue>(Operand)) {
122 // We have a reference to a global value. This should be added to
123 // the reference set unless it is a callee. Callees are handled
124 // specially by WriteFunction and are added to a separate list.
125 if (!(CB && CB->isCallee(&OI))) {
126 // If an ifunc has local linkage, do not add it into ref edges, and
127 // sets `RefLocalLinkageIFunc` to true. The referencer is not eligible
128 // for import. An ifunc doesn't have summary and ThinLTO cannot
129 // promote it; importing the referencer may cause linkage errors.
130 if (auto *GI = dyn_cast_if_present<GlobalIFunc>(GV);
131 GI && GI->hasLocalLinkage()) {
132 RefLocalLinkageIFunc = true;
133 continue;
134 }
135 RefEdges.insert(Index.getOrInsertValueInfo(GV));
136 }
137 continue;
138 }
139 if (Visited.insert(Operand).second)
140 Worklist.push_back(Operand);
141 }
142 }
143
144 const Instruction *I = dyn_cast<Instruction>(CurUser);
145 if (I) {
146 uint64_t TotalCount = 0;
147 // MaxNumVTableAnnotations is the maximum number of vtables annotated on
148 // the instruction.
149 auto ValueDataArray = getValueProfDataFromInst(
150 *I, IPVK_VTableTarget, MaxNumVTableAnnotations, TotalCount);
151
152 for (const auto &V : ValueDataArray)
153 RefEdges.insert(Index.getOrInsertValueInfo(/* VTableGUID = */
154 V.Value));
155 }
156 return HasBlockAddress;
157}
158
160 ProfileSummaryInfo *PSI) {
161 if (!PSI)
162 return CalleeInfo::HotnessType::Unknown;
163 if (PSI->isHotCount(ProfileCount))
164 return CalleeInfo::HotnessType::Hot;
165 if (PSI->isColdCount(ProfileCount))
166 return CalleeInfo::HotnessType::Cold;
167 return CalleeInfo::HotnessType::None;
168}
169
170static bool isNonRenamableLocal(const GlobalValue &GV) {
171 return GV.hasSection() && GV.hasLocalLinkage();
172}
173
174/// Determine whether this call has all constant integer arguments (excluding
175/// "this") and summarize it to VCalls or ConstVCalls as appropriate.
176static void addVCallToSet(
178 SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
179 &VCalls,
181 std::vector<FunctionSummary::ConstVCall>> &ConstVCalls) {
182 std::vector<uint64_t> Args;
183 // Start from the second argument to skip the "this" pointer.
184 for (auto &Arg : drop_begin(Call.CB.args())) {
185 auto *CI = dyn_cast<ConstantInt>(Arg);
186 if (!CI || CI->getBitWidth() > 64) {
187 VCalls.insert({Guid, Call.Offset});
188 return;
189 }
190 Args.push_back(CI->getZExtValue());
191 }
192 ConstVCalls.insert({{Guid, Call.Offset}, std::move(Args)});
193}
194
195/// If this intrinsic call requires that we add information to the function
196/// summary, do so via the non-constant reference arguments.
198 const CallInst *CI,
199 SetVector<GlobalValue::GUID, std::vector<GlobalValue::GUID>> &TypeTests,
200 SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
201 &TypeTestAssumeVCalls,
202 SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
203 &TypeCheckedLoadVCalls,
205 std::vector<FunctionSummary::ConstVCall>>
206 &TypeTestAssumeConstVCalls,
208 std::vector<FunctionSummary::ConstVCall>>
209 &TypeCheckedLoadConstVCalls,
210 DominatorTree &DT) {
211 switch (CI->getCalledFunction()->getIntrinsicID()) {
212 case Intrinsic::type_test:
213 case Intrinsic::public_type_test: {
214 auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
215 auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
216 if (!TypeId)
217 break;
218 GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
219
220 // Produce a summary from type.test intrinsics. We only summarize type.test
221 // intrinsics that are used other than by an llvm.assume intrinsic.
222 // Intrinsics that are assumed are relevant only to the devirtualization
223 // pass, not the type test lowering pass.
224 bool HasNonAssumeUses = llvm::any_of(CI->uses(), [](const Use &CIU) {
225 return !isa<AssumeInst>(CIU.getUser());
226 });
227 if (HasNonAssumeUses)
228 TypeTests.insert(Guid);
229
232 findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI, DT);
233 for (auto &Call : DevirtCalls)
234 addVCallToSet(Call, Guid, TypeTestAssumeVCalls,
235 TypeTestAssumeConstVCalls);
236
237 break;
238 }
239
240 case Intrinsic::type_checked_load_relative:
241 case Intrinsic::type_checked_load: {
242 auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(2));
243 auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
244 if (!TypeId)
245 break;
246 GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
247
251 bool HasNonCallUses = false;
252 findDevirtualizableCallsForTypeCheckedLoad(DevirtCalls, LoadedPtrs, Preds,
253 HasNonCallUses, CI, DT);
254 // Any non-call uses of the result of llvm.type.checked.load will
255 // prevent us from optimizing away the llvm.type.test.
256 if (HasNonCallUses)
257 TypeTests.insert(Guid);
258 for (auto &Call : DevirtCalls)
259 addVCallToSet(Call, Guid, TypeCheckedLoadVCalls,
260 TypeCheckedLoadConstVCalls);
261
262 break;
263 }
264 default:
265 break;
266 }
267}
268
269static bool isNonVolatileLoad(const Instruction *I) {
270 if (const auto *LI = dyn_cast<LoadInst>(I))
271 return !LI->isVolatile();
272
273 return false;
274}
275
276static bool isNonVolatileStore(const Instruction *I) {
277 if (const auto *SI = dyn_cast<StoreInst>(I))
278 return !SI->isVolatile();
279
280 return false;
281}
282
283// Returns true if the function definition must be unreachable.
284//
285// Note if this helper function returns true, `F` is guaranteed
286// to be unreachable; if it returns false, `F` might still
287// be unreachable but not covered by this helper function.
289 // A function must be unreachable if its entry block ends with an
290 // 'unreachable'.
291 assert(!F.isDeclaration());
292 return isa<UnreachableInst>(F.getEntryBlock().getTerminator());
293}
294
296 ModuleSummaryIndex &Index, const Module &M, const Function &F,
298 bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted,
299 bool IsThinLTO,
300 std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) {
301 // Summary not currently supported for anonymous functions, they should
302 // have been named.
303 assert(F.hasName());
304
305 unsigned NumInsts = 0;
306 // Map from callee ValueId to profile count. Used to accumulate profile
307 // counts for all static calls to a given callee.
309 std::vector<std::pair<ValueInfo, CalleeInfo>>>
310 CallGraphEdges;
311 SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges, LoadRefEdges,
312 StoreRefEdges;
315 TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
317 std::vector<FunctionSummary::ConstVCall>>
318 TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls;
319 ICallPromotionAnalysis ICallAnalysis;
321
322 // Add personality function, prefix data and prologue data to function's ref
323 // list.
324 bool HasLocalIFuncCallOrRef = false;
325 findRefEdges(Index, &F, RefEdges, Visited, HasLocalIFuncCallOrRef);
326 std::vector<const Instruction *> NonVolatileLoads;
327 std::vector<const Instruction *> NonVolatileStores;
328
329 std::vector<CallsiteInfo> Callsites;
330 std::vector<AllocInfo> Allocs;
331
332#ifndef NDEBUG
333 DenseSet<const CallBase *> CallsThatMayHaveMemprofSummary;
334#endif
335
336 bool HasInlineAsmMaybeReferencingInternal = false;
337 bool HasIndirBranchToBlockAddress = false;
338 bool HasUnknownCall = false;
339 bool MayThrow = false;
340 for (const BasicBlock &BB : F) {
341 // We don't allow inlining of function with indirect branch to blockaddress.
342 // If the blockaddress escapes the function, e.g., via a global variable,
343 // inlining may lead to an invalid cross-function reference. So we shouldn't
344 // import such function either.
345 if (BB.hasAddressTaken()) {
346 for (User *U : BlockAddress::get(const_cast<BasicBlock *>(&BB))->users())
347 if (!isa<CallBrInst>(*U)) {
348 HasIndirBranchToBlockAddress = true;
349 break;
350 }
351 }
352
353 for (const Instruction &I : BB) {
354 if (I.isDebugOrPseudoInst())
355 continue;
356 ++NumInsts;
357
358 // Regular LTO module doesn't participate in ThinLTO import,
359 // so no reference from it can be read/writeonly, since this
360 // would require importing variable as local copy
361 if (IsThinLTO) {
362 if (isNonVolatileLoad(&I)) {
363 // Postpone processing of non-volatile load instructions
364 // See comments below
365 Visited.insert(&I);
366 NonVolatileLoads.push_back(&I);
367 continue;
368 } else if (isNonVolatileStore(&I)) {
369 Visited.insert(&I);
370 NonVolatileStores.push_back(&I);
371 // All references from second operand of store (destination address)
372 // can be considered write-only if they're not referenced by any
373 // non-store instruction. References from first operand of store
374 // (stored value) can't be treated either as read- or as write-only
375 // so we add them to RefEdges as we do with all other instructions
376 // except non-volatile load.
377 Value *Stored = I.getOperand(0);
378 if (auto *GV = dyn_cast<GlobalValue>(Stored))
379 // findRefEdges will try to examine GV operands, so instead
380 // of calling it we should add GV to RefEdges directly.
381 RefEdges.insert(Index.getOrInsertValueInfo(GV));
382 else if (auto *U = dyn_cast<User>(Stored))
383 findRefEdges(Index, U, RefEdges, Visited, HasLocalIFuncCallOrRef);
384 continue;
385 }
386 }
387 findRefEdges(Index, &I, RefEdges, Visited, HasLocalIFuncCallOrRef);
388 const auto *CB = dyn_cast<CallBase>(&I);
389 if (!CB) {
390 if (I.mayThrow())
391 MayThrow = true;
392 continue;
393 }
394
395 const auto *CI = dyn_cast<CallInst>(&I);
396 // Since we don't know exactly which local values are referenced in inline
397 // assembly, conservatively mark the function as possibly referencing
398 // a local value from inline assembly to ensure we don't export a
399 // reference (which would require renaming and promotion of the
400 // referenced value).
401 if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm())
402 HasInlineAsmMaybeReferencingInternal = true;
403
404 auto *CalledValue = CB->getCalledOperand();
405 auto *CalledFunction = CB->getCalledFunction();
406 if (CalledValue && !CalledFunction) {
407 CalledValue = CalledValue->stripPointerCasts();
408 // Stripping pointer casts can reveal a called function.
409 CalledFunction = dyn_cast<Function>(CalledValue);
410 }
411 // Check if this is an alias to a function. If so, get the
412 // called aliasee for the checks below.
413 if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
414 assert(!CalledFunction && "Expected null called function in callsite for alias");
415 CalledFunction = dyn_cast<Function>(GA->getAliaseeObject());
416 }
417 // Check if this is a direct call to a known function or a known
418 // intrinsic, or an indirect call with profile data.
419 if (CalledFunction) {
420 if (CI && CalledFunction->isIntrinsic()) {
422 CI, TypeTests, TypeTestAssumeVCalls, TypeCheckedLoadVCalls,
423 TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls, DT);
424 continue;
425 }
426 // We should have named any anonymous globals
427 assert(CalledFunction->hasName());
428 auto ScaledCount = PSI->getProfileCount(*CB, BFI);
429 auto Hotness = ScaledCount ? getHotness(*ScaledCount, PSI)
430 : CalleeInfo::HotnessType::Unknown;
432 Hotness = CalleeInfo::HotnessType::Cold;
433
434 // Use the original CalledValue, in case it was an alias. We want
435 // to record the call edge to the alias in that case. Eventually
436 // an alias summary will be created to associate the alias and
437 // aliasee.
438 auto &ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo(
439 cast<GlobalValue>(CalledValue))];
440 ValueInfo.updateHotness(Hotness);
441 if (CB->isTailCall())
442 ValueInfo.setHasTailCall(true);
443 // Add the relative block frequency to CalleeInfo if there is no profile
444 // information.
445 if (BFI != nullptr && Hotness == CalleeInfo::HotnessType::Unknown) {
446 uint64_t BBFreq = BFI->getBlockFreq(&BB).getFrequency();
447 uint64_t EntryFreq = BFI->getEntryFreq().getFrequency();
448 ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq);
449 }
450 } else {
451 HasUnknownCall = true;
452 // If F is imported, a local linkage ifunc (e.g. target_clones on a
453 // static function) called by F will be cloned. Since summaries don't
454 // track ifunc, we do not know implementation functions referenced by
455 // the ifunc resolver need to be promoted in the exporter, and we will
456 // get linker errors due to cloned declarations for implementation
457 // functions. As a simple fix, just mark F as not eligible for import.
458 // Non-local ifunc is not cloned and does not have the issue.
459 if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
460 if (GI->hasLocalLinkage())
461 HasLocalIFuncCallOrRef = true;
462 // Skip inline assembly calls.
463 if (CI && CI->isInlineAsm())
464 continue;
465 // Skip direct calls.
466 if (!CalledValue || isa<Constant>(CalledValue))
467 continue;
468
469 // Check if the instruction has a callees metadata. If so, add callees
470 // to CallGraphEdges to reflect the references from the metadata, and
471 // to enable importing for subsequent indirect call promotion and
472 // inlining.
473 if (auto *MD = I.getMetadata(LLVMContext::MD_callees)) {
474 for (const auto &Op : MD->operands()) {
475 Function *Callee = mdconst::extract_or_null<Function>(Op);
476 if (Callee)
477 CallGraphEdges[Index.getOrInsertValueInfo(Callee)];
478 }
479 }
480
481 uint32_t NumCandidates;
482 uint64_t TotalCount;
483 auto CandidateProfileData =
484 ICallAnalysis.getPromotionCandidatesForInstruction(&I, TotalCount,
485 NumCandidates);
486 for (const auto &Candidate : CandidateProfileData)
487 CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]
488 .updateHotness(getHotness(Candidate.Count, PSI));
489 }
490
491 // Summarize memprof related metadata. This is only needed for ThinLTO.
492 if (!IsThinLTO)
493 continue;
494
495 // TODO: Skip indirect calls for now. Need to handle these better, likely
496 // by creating multiple Callsites, one per target, then speculatively
497 // devirtualize while applying clone info in the ThinLTO backends. This
498 // will also be important because we will have a different set of clone
499 // versions per target. This handling needs to match that in the ThinLTO
500 // backend so we handle things consistently for matching of callsite
501 // summaries to instructions.
502 if (!CalledFunction)
503 continue;
504
505 // Ensure we keep this analysis in sync with the handling in the ThinLTO
506 // backend (see MemProfContextDisambiguation::applyImport). Save this call
507 // so that we can skip it in checking the reverse case later.
509#ifndef NDEBUG
510 CallsThatMayHaveMemprofSummary.insert(CB);
511#endif
512
513 // Compute the list of stack ids first (so we can trim them from the stack
514 // ids on any MIBs).
516 I.getMetadata(LLVMContext::MD_callsite));
517 auto *MemProfMD = I.getMetadata(LLVMContext::MD_memprof);
518 if (MemProfMD) {
519 std::vector<MIBInfo> MIBs;
520 for (auto &MDOp : MemProfMD->operands()) {
521 auto *MIBMD = cast<const MDNode>(MDOp);
524 SmallVector<unsigned> StackIdIndices;
526 // Collapse out any on the allocation call (inlining).
527 for (auto ContextIter =
528 StackContext.beginAfterSharedPrefix(InstCallsite);
529 ContextIter != StackContext.end(); ++ContextIter) {
530 unsigned StackIdIdx = Index.addOrGetStackIdIndex(*ContextIter);
531 // If this is a direct recursion, simply skip the duplicate
532 // entries. If this is mutual recursion, handling is left to
533 // the LTO link analysis client.
534 if (StackIdIndices.empty() || StackIdIndices.back() != StackIdIdx)
535 StackIdIndices.push_back(StackIdIdx);
536 }
537 MIBs.push_back(
538 MIBInfo(getMIBAllocType(MIBMD), std::move(StackIdIndices)));
539 }
540 Allocs.push_back(AllocInfo(std::move(MIBs)));
541 } else if (!InstCallsite.empty()) {
542 SmallVector<unsigned> StackIdIndices;
543 for (auto StackId : InstCallsite)
544 StackIdIndices.push_back(Index.addOrGetStackIdIndex(StackId));
545 // Use the original CalledValue, in case it was an alias. We want
546 // to record the call edge to the alias in that case. Eventually
547 // an alias summary will be created to associate the alias and
548 // aliasee.
549 auto CalleeValueInfo =
550 Index.getOrInsertValueInfo(cast<GlobalValue>(CalledValue));
551 Callsites.push_back({CalleeValueInfo, StackIdIndices});
552 }
553 }
554 }
555
557 Index.addBlockCount(F.size());
558
559 std::vector<ValueInfo> Refs;
560 if (IsThinLTO) {
561 auto AddRefEdges = [&](const std::vector<const Instruction *> &Instrs,
564 for (const auto *I : Instrs) {
565 Cache.erase(I);
566 findRefEdges(Index, I, Edges, Cache, HasLocalIFuncCallOrRef);
567 }
568 };
569
570 // By now we processed all instructions in a function, except
571 // non-volatile loads and non-volatile value stores. Let's find
572 // ref edges for both of instruction sets
573 AddRefEdges(NonVolatileLoads, LoadRefEdges, Visited);
574 // We can add some values to the Visited set when processing load
575 // instructions which are also used by stores in NonVolatileStores.
576 // For example this can happen if we have following code:
577 //
578 // store %Derived* @foo, %Derived** bitcast (%Base** @bar to %Derived**)
579 // %42 = load %Derived*, %Derived** bitcast (%Base** @bar to %Derived**)
580 //
581 // After processing loads we'll add bitcast to the Visited set, and if
582 // we use the same set while processing stores, we'll never see store
583 // to @bar and @bar will be mistakenly treated as readonly.
585 AddRefEdges(NonVolatileStores, StoreRefEdges, StoreCache);
586
587 // If both load and store instruction reference the same variable
588 // we won't be able to optimize it. Add all such reference edges
589 // to RefEdges set.
590 for (const auto &VI : StoreRefEdges)
591 if (LoadRefEdges.remove(VI))
592 RefEdges.insert(VI);
593
594 unsigned RefCnt = RefEdges.size();
595 // All new reference edges inserted in two loops below are either
596 // read or write only. They will be grouped in the end of RefEdges
597 // vector, so we can use a single integer value to identify them.
598 for (const auto &VI : LoadRefEdges)
599 RefEdges.insert(VI);
600
601 unsigned FirstWORef = RefEdges.size();
602 for (const auto &VI : StoreRefEdges)
603 RefEdges.insert(VI);
604
605 Refs = RefEdges.takeVector();
606 for (; RefCnt < FirstWORef; ++RefCnt)
607 Refs[RefCnt].setReadOnly();
608
609 for (; RefCnt < Refs.size(); ++RefCnt)
610 Refs[RefCnt].setWriteOnly();
611 } else {
612 Refs = RefEdges.takeVector();
613 }
614 // Explicit add hot edges to enforce importing for designated GUIDs for
615 // sample PGO, to enable the same inlines as the profiled optimized binary.
616 for (auto &I : F.getImportGUIDs())
617 CallGraphEdges[Index.getOrInsertValueInfo(I)].updateHotness(
619 ? CalleeInfo::HotnessType::Cold
620 : CalleeInfo::HotnessType::Critical);
621
622#ifndef NDEBUG
623 // Make sure that all calls we decided could not have memprof summaries get a
624 // false value for mayHaveMemprofSummary, to ensure that this handling remains
625 // in sync with the ThinLTO backend handling.
626 if (IsThinLTO) {
627 for (const BasicBlock &BB : F) {
628 for (const Instruction &I : BB) {
629 const auto *CB = dyn_cast<CallBase>(&I);
630 if (!CB)
631 continue;
632 // We already checked these above.
633 if (CallsThatMayHaveMemprofSummary.count(CB))
634 continue;
636 }
637 }
638 }
639#endif
640
641 bool NonRenamableLocal = isNonRenamableLocal(F);
642 bool NotEligibleForImport =
643 NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
644 HasIndirBranchToBlockAddress || HasLocalIFuncCallOrRef;
646 F.getLinkage(), F.getVisibility(), NotEligibleForImport,
647 /* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable(),
648 GlobalValueSummary::ImportKind::Definition);
650 F.doesNotAccessMemory(), F.onlyReadsMemory() && !F.doesNotAccessMemory(),
651 F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(),
652 // FIXME: refactor this to use the same code that inliner is using.
653 // Don't try to import functions with noinline attribute.
654 F.getAttributes().hasFnAttr(Attribute::NoInline),
655 F.hasFnAttribute(Attribute::AlwaysInline),
656 F.hasFnAttribute(Attribute::NoUnwind), MayThrow, HasUnknownCall,
658 std::vector<FunctionSummary::ParamAccess> ParamAccesses;
659 if (auto *SSI = GetSSICallback(F))
660 ParamAccesses = SSI->getParamAccesses(Index);
661 auto FuncSummary = std::make_unique<FunctionSummary>(
662 Flags, NumInsts, FunFlags, /*EntryCount=*/0, std::move(Refs),
663 CallGraphEdges.takeVector(), TypeTests.takeVector(),
664 TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(),
665 TypeTestAssumeConstVCalls.takeVector(),
666 TypeCheckedLoadConstVCalls.takeVector(), std::move(ParamAccesses),
667 std::move(Callsites), std::move(Allocs));
668 if (NonRenamableLocal)
669 CantBePromoted.insert(F.getGUID());
670 Index.addGlobalValueSummary(F, std::move(FuncSummary));
671}
672
673/// Find function pointers referenced within the given vtable initializer
674/// (or subset of an initializer) \p I. The starting offset of \p I within
675/// the vtable initializer is \p StartingOffset. Any discovered function
676/// pointers are added to \p VTableFuncs along with their cumulative offset
677/// within the initializer.
678static void findFuncPointers(const Constant *I, uint64_t StartingOffset,
680 VTableFuncList &VTableFuncs,
681 const GlobalVariable &OrigGV) {
682 // First check if this is a function pointer.
683 if (I->getType()->isPointerTy()) {
684 auto C = I->stripPointerCasts();
685 auto A = dyn_cast<GlobalAlias>(C);
686 if (isa<Function>(C) || (A && isa<Function>(A->getAliasee()))) {
687 auto GV = dyn_cast<GlobalValue>(C);
688 assert(GV);
689 // We can disregard __cxa_pure_virtual as a possible call target, as
690 // calls to pure virtuals are UB.
691 if (GV && GV->getName() != "__cxa_pure_virtual")
692 VTableFuncs.push_back({Index.getOrInsertValueInfo(GV), StartingOffset});
693 return;
694 }
695 }
696
697 // Walk through the elements in the constant struct or array and recursively
698 // look for virtual function pointers.
699 const DataLayout &DL = M.getDataLayout();
700 if (auto *C = dyn_cast<ConstantStruct>(I)) {
701 StructType *STy = dyn_cast<StructType>(C->getType());
702 assert(STy);
703 const StructLayout *SL = DL.getStructLayout(C->getType());
704
705 for (auto EI : llvm::enumerate(STy->elements())) {
706 auto Offset = SL->getElementOffset(EI.index());
707 unsigned Op = SL->getElementContainingOffset(Offset);
708 findFuncPointers(cast<Constant>(I->getOperand(Op)),
709 StartingOffset + Offset, M, Index, VTableFuncs, OrigGV);
710 }
711 } else if (auto *C = dyn_cast<ConstantArray>(I)) {
712 ArrayType *ATy = C->getType();
713 Type *EltTy = ATy->getElementType();
714 uint64_t EltSize = DL.getTypeAllocSize(EltTy);
715 for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
716 findFuncPointers(cast<Constant>(I->getOperand(i)),
717 StartingOffset + i * EltSize, M, Index, VTableFuncs,
718 OrigGV);
719 }
720 } else if (const auto *CE = dyn_cast<ConstantExpr>(I)) {
721 // For relative vtables, the next sub-component should be a trunc.
722 if (CE->getOpcode() != Instruction::Trunc ||
723 !(CE = dyn_cast<ConstantExpr>(CE->getOperand(0))))
724 return;
725
726 // If this constant can be reduced to the offset between a function and a
727 // global, then we know this is a valid virtual function if the RHS is the
728 // original vtable we're scanning through.
729 if (CE->getOpcode() == Instruction::Sub) {
731 APSInt LHSOffset, RHSOffset;
732 if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHS, LHSOffset, DL) &&
733 IsConstantOffsetFromGlobal(CE->getOperand(1), RHS, RHSOffset, DL) &&
734 RHS == &OrigGV &&
735
736 // For relative vtables, this component should point to the callable
737 // function without any offsets.
738 LHSOffset == 0 &&
739
740 // Also, the RHS should always point to somewhere within the vtable.
741 RHSOffset <=
742 static_cast<uint64_t>(DL.getTypeAllocSize(OrigGV.getInitializer()->getType()))) {
743 findFuncPointers(LHS, StartingOffset, M, Index, VTableFuncs, OrigGV);
744 }
745 }
746 }
747}
748
749// Identify the function pointers referenced by vtable definition \p V.
751 const GlobalVariable &V, const Module &M,
752 VTableFuncList &VTableFuncs) {
753 if (!V.isConstant())
754 return;
755
756 findFuncPointers(V.getInitializer(), /*StartingOffset=*/0, M, Index,
757 VTableFuncs, V);
758
759#ifndef NDEBUG
760 // Validate that the VTableFuncs list is ordered by offset.
761 uint64_t PrevOffset = 0;
762 for (auto &P : VTableFuncs) {
763 // The findVFuncPointers traversal should have encountered the
764 // functions in offset order. We need to use ">=" since PrevOffset
765 // starts at 0.
766 assert(P.VTableOffset >= PrevOffset);
767 PrevOffset = P.VTableOffset;
768 }
769#endif
770}
771
772/// Record vtable definition \p V for each type metadata it references.
773static void
775 const GlobalVariable &V,
777 for (MDNode *Type : Types) {
778 auto TypeID = Type->getOperand(1).get();
779
781 cast<ConstantInt>(
782 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
783 ->getZExtValue();
784
785 if (auto *TypeId = dyn_cast<MDString>(TypeID))
786 Index.getOrInsertTypeIdCompatibleVtableSummary(TypeId->getString())
787 .push_back({Offset, Index.getOrInsertValueInfo(&V)});
788 }
789}
790
792 const GlobalVariable &V,
793 DenseSet<GlobalValue::GUID> &CantBePromoted,
794 const Module &M,
798 bool RefLocalIFunc = false;
799 bool HasBlockAddress =
800 findRefEdges(Index, &V, RefEdges, Visited, RefLocalIFunc);
801 const bool NotEligibleForImport = (HasBlockAddress || RefLocalIFunc);
802 bool NonRenamableLocal = isNonRenamableLocal(V);
804 V.getLinkage(), V.getVisibility(), NonRenamableLocal,
805 /* Live = */ false, V.isDSOLocal(), V.canBeOmittedFromSymbolTable(),
807
808 VTableFuncList VTableFuncs;
809 // If splitting is not enabled, then we compute the summary information
810 // necessary for index-based whole program devirtualization.
811 if (!Index.enableSplitLTOUnit()) {
812 Types.clear();
813 V.getMetadata(LLVMContext::MD_type, Types);
814 if (!Types.empty()) {
815 // Identify the function pointers referenced by this vtable definition.
816 computeVTableFuncs(Index, V, M, VTableFuncs);
817
818 // Record this vtable definition for each type metadata it references.
820 }
821 }
822
823 // Don't mark variables we won't be able to internalize as read/write-only.
824 bool CanBeInternalized =
825 !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() &&
826 !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass();
827 bool Constant = V.isConstant();
828 GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized,
829 Constant ? false : CanBeInternalized,
830 Constant, V.getVCallVisibility());
831 auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags,
832 RefEdges.takeVector());
833 if (NonRenamableLocal)
834 CantBePromoted.insert(V.getGUID());
835 if (NotEligibleForImport)
836 GVarSummary->setNotEligibleToImport();
837 if (!VTableFuncs.empty())
838 GVarSummary->setVTableFuncs(VTableFuncs);
839 Index.addGlobalValueSummary(V, std::move(GVarSummary));
840}
841
843 DenseSet<GlobalValue::GUID> &CantBePromoted) {
844 // Skip summary for indirect function aliases as summary for aliasee will not
845 // be emitted.
846 const GlobalObject *Aliasee = A.getAliaseeObject();
847 if (isa<GlobalIFunc>(Aliasee))
848 return;
849 bool NonRenamableLocal = isNonRenamableLocal(A);
851 A.getLinkage(), A.getVisibility(), NonRenamableLocal,
852 /* Live = */ false, A.isDSOLocal(), A.canBeOmittedFromSymbolTable(),
854 auto AS = std::make_unique<AliasSummary>(Flags);
855 auto AliaseeVI = Index.getValueInfo(Aliasee->getGUID());
856 assert(AliaseeVI && "Alias expects aliasee summary to be available");
857 assert(AliaseeVI.getSummaryList().size() == 1 &&
858 "Expected a single entry per aliasee in per-module index");
859 AS->setAliasee(AliaseeVI, AliaseeVI.getSummaryList()[0].get());
860 if (NonRenamableLocal)
861 CantBePromoted.insert(A.getGUID());
862 Index.addGlobalValueSummary(A, std::move(AS));
863}
864
865// Set LiveRoot flag on entries matching the given value name.
867 if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))
868 for (const auto &Summary : VI.getSummaryList())
869 Summary->setLive(true);
870}
871
873 const Module &M,
874 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
876 std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) {
877 assert(PSI);
878 bool EnableSplitLTOUnit = false;
879 bool UnifiedLTO = false;
880 if (auto *MD = mdconst::extract_or_null<ConstantInt>(
881 M.getModuleFlag("EnableSplitLTOUnit")))
882 EnableSplitLTOUnit = MD->getZExtValue();
883 if (auto *MD =
884 mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("UnifiedLTO")))
885 UnifiedLTO = MD->getZExtValue();
886 ModuleSummaryIndex Index(/*HaveGVs=*/true, EnableSplitLTOUnit, UnifiedLTO);
887
888 // Identify the local values in the llvm.used and llvm.compiler.used sets,
889 // which should not be exported as they would then require renaming and
890 // promotion, but we may have opaque uses e.g. in inline asm. We collect them
891 // here because we use this information to mark functions containing inline
892 // assembly calls as not importable.
895 // First collect those in the llvm.used set.
896 collectUsedGlobalVariables(M, Used, /*CompilerUsed=*/false);
897 // Next collect those in the llvm.compiler.used set.
898 collectUsedGlobalVariables(M, Used, /*CompilerUsed=*/true);
899 DenseSet<GlobalValue::GUID> CantBePromoted;
900 for (auto *V : Used) {
901 if (V->hasLocalLinkage()) {
902 LocalsUsed.insert(V);
903 CantBePromoted.insert(V->getGUID());
904 }
905 }
906
907 bool HasLocalInlineAsmSymbol = false;
908 if (!M.getModuleInlineAsm().empty()) {
909 // Collect the local values defined by module level asm, and set up
910 // summaries for these symbols so that they can be marked as NoRename,
911 // to prevent export of any use of them in regular IR that would require
912 // renaming within the module level asm. Note we don't need to create a
913 // summary for weak or global defs, as they don't need to be flagged as
914 // NoRename, and defs in module level asm can't be imported anyway.
915 // Also, any values used but not defined within module level asm should
916 // be listed on the llvm.used or llvm.compiler.used global and marked as
917 // referenced from there.
920 // Symbols not marked as Weak or Global are local definitions.
923 return;
924 HasLocalInlineAsmSymbol = true;
925 GlobalValue *GV = M.getNamedValue(Name);
926 if (!GV)
927 return;
928 assert(GV->isDeclaration() && "Def in module asm already has definition");
931 /* NotEligibleToImport = */ true,
932 /* Live = */ true,
933 /* Local */ GV->isDSOLocal(), GV->canBeOmittedFromSymbolTable(),
935 CantBePromoted.insert(GV->getGUID());
936 // Create the appropriate summary type.
937 if (Function *F = dyn_cast<Function>(GV)) {
938 std::unique_ptr<FunctionSummary> Summary =
939 std::make_unique<FunctionSummary>(
940 GVFlags, /*InstCount=*/0,
942 F->hasFnAttribute(Attribute::ReadNone),
943 F->hasFnAttribute(Attribute::ReadOnly),
944 F->hasFnAttribute(Attribute::NoRecurse),
945 F->returnDoesNotAlias(),
946 /* NoInline = */ false,
947 F->hasFnAttribute(Attribute::AlwaysInline),
948 F->hasFnAttribute(Attribute::NoUnwind),
949 /* MayThrow */ true,
950 /* HasUnknownCall */ true,
951 /* MustBeUnreachable */ false},
952 /*EntryCount=*/0, ArrayRef<ValueInfo>{},
961 Index.addGlobalValueSummary(*GV, std::move(Summary));
962 } else {
963 std::unique_ptr<GlobalVarSummary> Summary =
964 std::make_unique<GlobalVarSummary>(
965 GVFlags,
967 false, false, cast<GlobalVariable>(GV)->isConstant(),
970 Index.addGlobalValueSummary(*GV, std::move(Summary));
971 }
972 });
973 }
974
975 bool IsThinLTO = true;
976 if (auto *MD =
977 mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
978 IsThinLTO = MD->getZExtValue();
979
980 // Compute summaries for all functions defined in module, and save in the
981 // index.
982 for (const auto &F : M) {
983 if (F.isDeclaration())
984 continue;
985
986 DominatorTree DT(const_cast<Function &>(F));
987 BlockFrequencyInfo *BFI = nullptr;
988 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
989 if (GetBFICallback)
990 BFI = GetBFICallback(F);
991 else if (F.hasProfileData()) {
992 LoopInfo LI{DT};
993 BranchProbabilityInfo BPI{F, LI};
994 BFIPtr = std::make_unique<BlockFrequencyInfo>(F, BPI, LI);
995 BFI = BFIPtr.get();
996 }
997
998 computeFunctionSummary(Index, M, F, BFI, PSI, DT,
999 !LocalsUsed.empty() || HasLocalInlineAsmSymbol,
1000 CantBePromoted, IsThinLTO, GetSSICallback);
1001 }
1002
1003 // Compute summaries for all variables defined in module, and save in the
1004 // index.
1006 for (const GlobalVariable &G : M.globals()) {
1007 if (G.isDeclaration())
1008 continue;
1009 computeVariableSummary(Index, G, CantBePromoted, M, Types);
1010 }
1011
1012 // Compute summaries for all aliases defined in module, and save in the
1013 // index.
1014 for (const GlobalAlias &A : M.aliases())
1015 computeAliasSummary(Index, A, CantBePromoted);
1016
1017 // Iterate through ifuncs, set their resolvers all alive.
1018 for (const GlobalIFunc &I : M.ifuncs()) {
1019 I.applyAlongResolverPath([&Index](const GlobalValue &GV) {
1020 Index.getGlobalValueSummary(GV)->setLive(true);
1021 });
1022 }
1023
1024 for (auto *V : LocalsUsed) {
1025 auto *Summary = Index.getGlobalValueSummary(*V);
1026 assert(Summary && "Missing summary for global value");
1027 Summary->setNotEligibleToImport();
1028 }
1029
1030 // The linker doesn't know about these LLVM produced values, so we need
1031 // to flag them as live in the index to ensure index-based dead value
1032 // analysis treats them as live roots of the analysis.
1033 setLiveRoot(Index, "llvm.used");
1034 setLiveRoot(Index, "llvm.compiler.used");
1035 setLiveRoot(Index, "llvm.global_ctors");
1036 setLiveRoot(Index, "llvm.global_dtors");
1037 setLiveRoot(Index, "llvm.global.annotations");
1038
1039 for (auto &GlobalList : Index) {
1040 // Ignore entries for references that are undefined in the current module.
1041 if (GlobalList.second.SummaryList.empty())
1042 continue;
1043
1044 assert(GlobalList.second.SummaryList.size() == 1 &&
1045 "Expected module's index to have one summary per GUID");
1046 auto &Summary = GlobalList.second.SummaryList[0];
1047 if (!IsThinLTO) {
1048 Summary->setNotEligibleToImport();
1049 continue;
1050 }
1051
1052 bool AllRefsCanBeExternallyReferenced =
1053 llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
1054 return !CantBePromoted.count(VI.getGUID());
1055 });
1056 if (!AllRefsCanBeExternallyReferenced) {
1057 Summary->setNotEligibleToImport();
1058 continue;
1059 }
1060
1061 if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
1062 bool AllCallsCanBeExternallyReferenced = llvm::all_of(
1063 FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
1064 return !CantBePromoted.count(Edge.first.getGUID());
1065 });
1066 if (!AllCallsCanBeExternallyReferenced)
1067 Summary->setNotEligibleToImport();
1068 }
1069 }
1070
1071 if (!ModuleSummaryDotFile.empty()) {
1072 std::error_code EC;
1073 raw_fd_ostream OSDot(ModuleSummaryDotFile, EC, sys::fs::OpenFlags::OF_Text);
1074 if (EC)
1075 report_fatal_error(Twine("Failed to open dot file ") +
1076 ModuleSummaryDotFile + ": " + EC.message() + "\n");
1077 Index.exportToDot(OSDot, {});
1078 }
1079
1080 return Index;
1081}
1082
1083AnalysisKey ModuleSummaryIndexAnalysis::Key;
1084
1088 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1089 bool NeedSSI = needsParamAccessSummary(M);
1091 M,
1092 [&FAM](const Function &F) {
1094 *const_cast<Function *>(&F));
1095 },
1096 &PSI,
1097 [&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * {
1098 return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>(
1099 const_cast<Function &>(F))
1100 : nullptr;
1101 });
1102}
1103
1105
1107 "Module Summary Analysis", false, true)
1113
1115 return new ModuleSummaryIndexWrapperPass();
1116}
1117
1119 : ModulePass(ID) {
1121}
1122
1124 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
1125 bool NeedSSI = needsParamAccessSummary(M);
1127 M,
1128 [this](const Function &F) {
1129 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
1130 *const_cast<Function *>(&F))
1131 .getBFI());
1132 },
1133 PSI,
1134 [&](const Function &F) -> const StackSafetyInfo * {
1135 return NeedSSI ? &getAnalysis<StackSafetyInfoWrapperPass>(
1136 const_cast<Function &>(F))
1137 .getResult()
1138 : nullptr;
1139 }));
1140 return false;
1141}
1142
1144 Index.reset();
1145 return false;
1146}
1147
1149 AU.setPreservesAll();
1153}
1154
1156
1162}
1163
1165 AnalysisUsage &AU) const {
1166 AU.setPreservesAll();
1167}
1168
1170 const ModuleSummaryIndex *Index) {
1172}
1173
1175 "Module summary info", false, true)
1176
1178 if (!CB)
1179 return false;
1180 if (CB->isDebugOrPseudoInst())
1181 return false;
1182 auto *CI = dyn_cast<CallInst>(CB);
1183 auto *CalledValue = CB->getCalledOperand();
1184 auto *CalledFunction = CB->getCalledFunction();
1185 if (CalledValue && !CalledFunction) {
1186 CalledValue = CalledValue->stripPointerCasts();
1187 // Stripping pointer casts can reveal a called function.
1188 CalledFunction = dyn_cast<Function>(CalledValue);
1189 }
1190 // Check if this is an alias to a function. If so, get the
1191 // called aliasee for the checks below.
1192 if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
1193 assert(!CalledFunction &&
1194 "Expected null called function in callsite for alias");
1195 CalledFunction = dyn_cast<Function>(GA->getAliaseeObject());
1196 }
1197 // Check if this is a direct call to a known function or a known
1198 // intrinsic, or an indirect call with profile data.
1199 if (CalledFunction) {
1200 if (CI && CalledFunction->isIntrinsic())
1201 return false;
1202 } else {
1203 // TODO: For now skip indirect calls. See comments in
1204 // computeFunctionSummary for what is needed to handle this.
1205 return false;
1206 }
1207 return true;
1208}
aarch64 promote const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool isConstant(const MachineInstr &MI)
This file contains the simple types necessary to represent the attributes associated with functions a...
basic Basic Alias true
block Block Frequency Analysis
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:686
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
iv users
Definition: IVUsers.cpp:48
Interface to identify indirect call promotion candidates.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This file implements a map that provides insertion order iteration.
This file contains the declarations for metadata subclasses.
static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid, SetVector< FunctionSummary::VFuncId, std::vector< FunctionSummary::VFuncId > > &VCalls, SetVector< FunctionSummary::ConstVCall, std::vector< FunctionSummary::ConstVCall > > &ConstVCalls)
Determine whether this call has all constant integer arguments (excluding "this") and summarize it to...
cl::opt< unsigned > MaxNumVTableAnnotations
static void computeVTableFuncs(ModuleSummaryIndex &Index, const GlobalVariable &V, const Module &M, VTableFuncList &VTableFuncs)
static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A, DenseSet< GlobalValue::GUID > &CantBePromoted)
static void findFuncPointers(const Constant *I, uint64_t StartingOffset, const Module &M, ModuleSummaryIndex &Index, VTableFuncList &VTableFuncs, const GlobalVariable &OrigGV)
Find function pointers referenced within the given vtable initializer (or subset of an initializer) I...
static void computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V, DenseSet< GlobalValue::GUID > &CantBePromoted, const Module &M, SmallVectorImpl< MDNode * > &Types)
static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name)
static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount, ProfileSummaryInfo *PSI)
static bool isNonVolatileLoad(const Instruction *I)
cl::opt< bool > ScalePartialSampleProfileWorkingSetSize
static bool isNonRenamableLocal(const GlobalValue &GV)
static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, const Function &F, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT, bool HasLocalsInUsedOrAsm, DenseSet< GlobalValue::GUID > &CantBePromoted, bool IsThinLTO, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback)
static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, SetVector< ValueInfo, std::vector< ValueInfo > > &RefEdges, SmallPtrSet< const User *, 8 > &Visited, bool &RefLocalLinkageIFunc)
static cl::opt< FunctionSummary::ForceSummaryHotnessType, true > FSEC("force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold), cl::desc("Force all edges in the function summary to cold"), cl::values(clEnumValN(FunctionSummary::FSHT_None, "none", "None."), clEnumValN(FunctionSummary::FSHT_AllNonCritical, "all-non-critical", "All non-critical edges."), clEnumValN(FunctionSummary::FSHT_All, "all", "All edges.")))
static bool mustBeUnreachableFunction(const Function &F)
static bool isNonVolatileStore(const Instruction *I)
module summary analysis
static cl::opt< std::string > ModuleSummaryDotFile("module-summary-dot-file", cl::Hidden, cl::value_desc("filename"), cl::desc("File to emit dot graph of new summary into"))
static void addIntrinsicToSummary(const CallInst *CI, SetVector< GlobalValue::GUID, std::vector< GlobalValue::GUID > > &TypeTests, SetVector< FunctionSummary::VFuncId, std::vector< FunctionSummary::VFuncId > > &TypeTestAssumeVCalls, SetVector< FunctionSummary::VFuncId, std::vector< FunctionSummary::VFuncId > > &TypeCheckedLoadVCalls, SetVector< FunctionSummary::ConstVCall, std::vector< FunctionSummary::ConstVCall > > &TypeTestAssumeConstVCalls, SetVector< FunctionSummary::ConstVCall, std::vector< FunctionSummary::ConstVCall > > &TypeCheckedLoadConstVCalls, DominatorTree &DT)
If this intrinsic call requires that we add information to the function summary, do so via the non-co...
static void recordTypeIdCompatibleVtableReferences(ModuleSummaryIndex &Index, const GlobalVariable &V, SmallVectorImpl< MDNode * > &Types)
Record vtable definition V for each type metadata it references.
This is the interface to build a ModuleSummaryIndex for a module.
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
Module.h This file contains the declarations for the Module class.
#define P(N)
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:59
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This defines the Use class.
Value * RHS
Value * LHS
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:23
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:405
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Definition: Constants.cpp:1833
Analysis pass which computes BlockFrequencyInfo.
Legacy analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Analysis providing branch probability information.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1236
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1465
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1410
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
Definition: Constant.h:41
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
std::pair< ValueInfo, CalleeInfo > EdgeTy
<CalleeValueInfo, CalleeInfo> call edge pair.
ForceSummaryHotnessType
Types for -force-summary-edges-cold debugging option.
Class to represent profile counts.
Definition: Function.h:289
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:242
bool isDSOLocal() const
Definition: GlobalValue.h:305
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:290
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: Globals.cpp:75
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:595
@ DefaultVisibility
The GV is visible.
Definition: GlobalValue.h:67
bool hasSection() const
Definition: GlobalValue.h:290
bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
Definition: Globals.cpp:419
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
ArrayRef< InstrProfValueData > getPromotionCandidatesForInstruction(const Instruction *I, uint64_t &TotalCount, uint32_t &NumCandidates)
Returns reference to array of InstrProfValueData for the given instruction I.
Legacy wrapper pass to provide the ModuleSummaryIndex object.
ImmutableModuleSummaryIndexWrapperPass(const ModuleSummaryIndex *Index=nullptr)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:282
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:563
Metadata node.
Definition: Metadata.h:1067
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
VectorType takeVector()
Clear the MapVector and return the underlying vector.
Definition: MapVector.h:55
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
Result run(Module &M, ModuleAnalysisManager &AM)
Legacy wrapper pass to provide the ModuleSummaryIndex object.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static void CollectAsmSymbols(const Module &M, function_ref< void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol)
Parse inline ASM and collect the symbols that are defined or referenced in the current module.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
std::optional< uint64_t > getProfileCount(const CallBase &CallInst, BlockFrequencyInfo *BFI, bool AllowSynthetic=false) const
Returns the profile count for CallInst.
bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
A vector that has set insertion semantics.
Definition: SetVector.h:57
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:188
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:98
Vector takeVector()
Clear the SetVector and return the underlying vector.
Definition: SetVector.h:87
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:344
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:479
bool empty() const
Definition: SmallVector.h:94
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StackSafetyInfo wrapper for the new pass manager.
StackSafetyInfo wrapper for the legacy pass manager.
Interface to access stack safety analysis results for single function.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition: DataLayout.h:622
unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
Definition: DataLayout.cpp:92
TypeSize getElementOffset(unsigned Idx) const
Definition: DataLayout.h:651
Class to represent struct types.
Definition: DerivedTypes.h:216
ArrayRef< Type * > elements() const
Definition: DerivedTypes.h:333
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
TypeID
Definitions of all of the base types for the Type system.
Definition: Type.h:54
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
iterator_range< use_iterator > uses()
Definition: Value.h:376
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
CallStackIterator end() const
CallStackIterator beginAfterSharedPrefix(CallStack &Other)
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:471
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:711
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:463
AllocationType getMIBAllocType(const MDNode *MIB)
Returns the allocation type from an MIB metadata node.
MDNode * getMIBStackNode(const MDNode *MIB)
Returns the stack node from an MIB metadata node.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1722
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
Definition: STLExtras.h:2400
bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset, const DataLayout &DL, DSOLocalEquivalent **DSOEquiv=nullptr)
If this constant is a constant offset from a global, return the global and the constant.
std::unique_ptr< InstrProfValueData[]> getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint32_t &ActualNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
Definition: InstrProf.cpp:1372
FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold
bool needsParamAccessSummary(const Module &M)
ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})
Direct function to compute a ModuleSummaryIndex from a given module.
void initializeModuleSummaryIndexWrapperPassPass(PassRegistry &)
std::vector< VirtFuncOffset > VTableFuncList
List of functions referenced by a particular vtable definition.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
void findDevirtualizableCallsForTypeCheckedLoad(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< Instruction * > &LoadedPtrs, SmallVectorImpl< Instruction * > &Preds, bool &HasNonCallUses, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.checked.load, find all devirtualizable call sites based on t...
ModulePass * createModuleSummaryIndexWrapperPass()
ImmutablePass * createImmutableModuleSummaryIndexWrapperPass(const ModuleSummaryIndex *Index)
void initializeImmutableModuleSummaryIndexWrapperPassPass(PassRegistry &)
bool mayHaveMemprofSummary(const CallBase *CB)
Returns true if the instruction could have memprof metadata, used to ensure consistency between summa...
void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst * > &Assumes, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.test, find all devirtualizable call sites based on the call ...
GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...
Definition: Module.cpp:854
Summary of memprof metadata on allocations.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:28
A call site that could be devirtualized.
A specification for a virtual function call with all constant integer arguments.
Flags specific to function summaries.
An "identifier" for a virtual function.
Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield.
Summary of a single MIB in a memprof metadata on allocations.
Struct that holds a reference to a particular GUID in a global value summary.