63#define DEBUG_TYPE "module-summary-analysis"
74 cl::desc(
"Force all edges in the function summary to cold"),
77 "all-non-critical",
"All non-critical edges."),
82 cl::desc(
"File to emit dot graph of new summary into"));
87 "Enable MemProf support for summarizing and cloning indirect calls"));
111 bool &RefLocalLinkageIFunc) {
112 bool HasBlockAddress =
false;
114 if (Visited.
insert(CurUser).second)
117 while (!Worklist.
empty()) {
119 const auto *CB = dyn_cast<CallBase>(U);
121 for (
const auto &OI : U->operands()) {
122 const User *Operand = dyn_cast<User>(OI);
125 if (isa<BlockAddress>(Operand)) {
126 HasBlockAddress =
true;
129 if (
auto *GV = dyn_cast<GlobalValue>(Operand)) {
133 if (!(CB && CB->isCallee(&OI))) {
138 if (
auto *GI = dyn_cast_if_present<GlobalIFunc>(GV);
139 GI && GI->hasLocalLinkage()) {
140 RefLocalLinkageIFunc =
true;
143 RefEdges.insert(Index.getOrInsertValueInfo(GV));
147 if (Visited.
insert(Operand).second)
160 for (
const auto &V : ValueDataArray)
161 RefEdges.insert(Index.getOrInsertValueInfo(
164 return HasBlockAddress;
170 return CalleeInfo::HotnessType::Unknown;
172 return CalleeInfo::HotnessType::Hot;
174 return CalleeInfo::HotnessType::Cold;
175 return CalleeInfo::HotnessType::None;
189 std::vector<FunctionSummary::ConstVCall>> &ConstVCalls) {
190 std::vector<uint64_t> Args;
192 for (
auto &Arg :
drop_begin(Call.CB.args())) {
193 auto *CI = dyn_cast<ConstantInt>(Arg);
194 if (!CI || CI->getBitWidth() > 64) {
195 VCalls.insert({
Guid, Call.Offset});
198 Args.push_back(CI->getZExtValue());
200 ConstVCalls.insert({{
Guid, Call.Offset}, std::move(Args)});
209 &TypeTestAssumeVCalls,
211 &TypeCheckedLoadVCalls,
213 std::vector<FunctionSummary::ConstVCall>>
214 &TypeTestAssumeConstVCalls,
216 std::vector<FunctionSummary::ConstVCall>>
217 &TypeCheckedLoadConstVCalls,
220 case Intrinsic::type_test:
221 case Intrinsic::public_type_test: {
222 auto *TypeMDVal = cast<MetadataAsValue>(CI->
getArgOperand(1));
223 auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
234 return !isa<AssumeInst>(CIU.getUser());
236 if (HasNonAssumeUses)
237 TypeTests.insert(
Guid);
242 for (
auto &Call : DevirtCalls)
244 TypeTestAssumeConstVCalls);
249 case Intrinsic::type_checked_load_relative:
250 case Intrinsic::type_checked_load: {
251 auto *TypeMDVal = cast<MetadataAsValue>(CI->
getArgOperand(2));
252 auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
261 bool HasNonCallUses =
false;
263 HasNonCallUses, CI, DT);
267 TypeTests.insert(
Guid);
268 for (
auto &Call : DevirtCalls)
270 TypeCheckedLoadConstVCalls);
280 if (
const auto *LI = dyn_cast<LoadInst>(
I))
281 return !LI->isVolatile();
287 if (
const auto *SI = dyn_cast<StoreInst>(
I))
288 return !SI->isVolatile();
302 return isa<UnreachableInst>(
F.getEntryBlock().getTerminator());
315 unsigned NumInsts = 0;
325 TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
327 std::vector<FunctionSummary::ConstVCall>>
328 TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls;
334 bool HasLocalIFuncCallOrRef =
false;
335 findRefEdges(Index, &
F, RefEdges, Visited, HasLocalIFuncCallOrRef);
336 std::vector<const Instruction *> NonVolatileLoads;
337 std::vector<const Instruction *> NonVolatileStores;
339 std::vector<CallsiteInfo> Callsites;
340 std::vector<AllocInfo> Allocs;
346 bool HasInlineAsmMaybeReferencingInternal =
false;
347 bool HasIndirBranchToBlockAddress =
false;
348 bool HasUnknownCall =
false;
349 bool MayThrow =
false;
355 if (BB.hasAddressTaken()) {
357 if (!isa<CallBrInst>(*U)) {
358 HasIndirBranchToBlockAddress =
true;
364 if (
I.isDebugOrPseudoInst())
376 NonVolatileLoads.push_back(&
I);
380 NonVolatileStores.push_back(&
I);
387 Value *Stored =
I.getOperand(0);
388 if (
auto *GV = dyn_cast<GlobalValue>(Stored))
391 RefEdges.
insert(Index.getOrInsertValueInfo(GV));
392 else if (
auto *U = dyn_cast<User>(Stored))
393 findRefEdges(Index, U, RefEdges, Visited, HasLocalIFuncCallOrRef);
397 findRefEdges(Index, &
I, RefEdges, Visited, HasLocalIFuncCallOrRef);
398 const auto *CB = dyn_cast<CallBase>(&
I);
405 const auto *CI = dyn_cast<CallInst>(&
I);
411 if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm())
412 HasInlineAsmMaybeReferencingInternal =
true;
419 auto *CalledValue = CB->getCalledOperand();
420 auto *CalledFunction = CB->getCalledFunction();
421 if (CalledValue && !CalledFunction) {
422 CalledValue = CalledValue->stripPointerCasts();
424 CalledFunction = dyn_cast<Function>(CalledValue);
428 if (
auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
429 assert(!CalledFunction &&
"Expected null called function in callsite for alias");
430 CalledFunction = dyn_cast<Function>(GA->getAliaseeObject());
434 if (CalledFunction) {
435 if (CI && CalledFunction->isIntrinsic()) {
437 CI, TypeTests, TypeTestAssumeVCalls, TypeCheckedLoadVCalls,
438 TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls, DT);
442 assert(CalledFunction->hasName());
444 auto Hotness = ScaledCount ?
getHotness(*ScaledCount, PSI)
445 : CalleeInfo::HotnessType::Unknown;
447 Hotness = CalleeInfo::HotnessType::Cold;
453 auto &
ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo(
454 cast<GlobalValue>(CalledValue))];
456 if (CB->isTailCall())
460 if (BFI !=
nullptr && Hotness == CalleeInfo::HotnessType::Unknown) {
462 uint64_t EntryFreq = BFI->getEntryFreq().getFrequency();
466 HasUnknownCall =
true;
474 if (
auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
475 if (GI->hasLocalLinkage())
476 HasLocalIFuncCallOrRef =
true;
478 if (CI && CI->isInlineAsm())
481 if (!CalledValue || isa<Constant>(CalledValue))
488 if (
auto *MD =
I.getMetadata(LLVMContext::MD_callees)) {
489 for (
const auto &
Op : MD->operands()) {
490 Function *Callee = mdconst::extract_or_null<Function>(
Op);
492 CallGraphEdges[Index.getOrInsertValueInfo(Callee)];
496 CandidateProfileData =
499 for (
const auto &Candidate : CandidateProfileData)
500 CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]
501 .updateHotness(
getHotness(Candidate.Count, PSI));
517 CallsThatMayHaveMemprofSummary.
insert(CB);
523 I.getMetadata(LLVMContext::MD_callsite));
524 auto *MemProfMD =
I.getMetadata(LLVMContext::MD_memprof);
526 std::vector<MIBInfo> MIBs;
527 std::vector<std::vector<ContextTotalSize>> ContextSizeInfos;
528 bool HasNonZeroContextSizeInfos =
false;
529 for (
auto &MDOp : MemProfMD->operands()) {
530 auto *MIBMD = cast<const MDNode>(MDOp);
536 for (
auto ContextIter =
538 ContextIter != StackContext.
end(); ++ContextIter) {
539 unsigned StackIdIdx = Index.addOrGetStackIdIndex(*ContextIter);
543 if (StackIdIndices.
empty() || StackIdIndices.
back() != StackIdIdx)
548 assert(MIBMD->getNumOperands() > 2 ||
550 if (MIBMD->getNumOperands() > 2) {
551 std::vector<ContextTotalSize> ContextSizes;
552 for (
unsigned I = 2;
I < MIBMD->getNumOperands();
I++) {
553 MDNode *ContextSizePair = dyn_cast<MDNode>(MIBMD->getOperand(
I));
555 uint64_t FullStackId = mdconst::dyn_extract<ConstantInt>(
558 uint64_t TS = mdconst::dyn_extract<ConstantInt>(
561 ContextSizes.push_back({FullStackId, TS});
565 HasNonZeroContextSizeInfos =
true;
566 ContextSizeInfos.push_back(std::move(ContextSizes));
575 ContextSizeInfos.push_back({{0, 0}});
580 Allocs.push_back(
AllocInfo(std::move(MIBs)));
581 assert(HasNonZeroContextSizeInfos ||
587 if (HasNonZeroContextSizeInfos) {
588 assert(Allocs.back().MIBs.size() == ContextSizeInfos.size());
589 Allocs.back().ContextSizeInfos = std::move(ContextSizeInfos);
591 }
else if (!InstCallsite.
empty()) {
593 for (
auto StackId : InstCallsite)
594 StackIdIndices.
push_back(Index.addOrGetStackIdIndex(StackId));
595 if (CalledFunction) {
600 auto CalleeValueInfo =
601 Index.getOrInsertValueInfo(cast<GlobalValue>(CalledValue));
602 Callsites.push_back({CalleeValueInfo, StackIdIndices});
609 for (
const auto &Candidate : CandidateProfileData) {
610 auto CalleeValueInfo = Index.getOrInsertValueInfo(Candidate.Value);
611 Callsites.push_back({CalleeValueInfo, StackIdIndices});
619 Index.addBlockCount(
F.size());
624 [&](
const std::vector<const Instruction *> &Instrs,
627 for (
const auto *
I : Instrs) {
629 findRefEdges(Index,
I, Edges, Cache, HasLocalIFuncCallOrRef);
636 AddRefEdges(NonVolatileLoads, LoadRefEdges, Visited);
648 AddRefEdges(NonVolatileStores, StoreRefEdges, StoreCache);
653 for (
const auto &VI : StoreRefEdges)
654 if (LoadRefEdges.
remove(VI))
657 unsigned RefCnt = RefEdges.
size();
663 unsigned FirstWORef = RefEdges.
size();
667 for (; RefCnt < FirstWORef; ++RefCnt)
668 Refs[RefCnt].setReadOnly();
670 for (; RefCnt < Refs.
size(); ++RefCnt)
671 Refs[RefCnt].setWriteOnly();
677 for (
auto &
I :
F.getImportGUIDs())
678 CallGraphEdges[Index.getOrInsertValueInfo(
I)].updateHotness(
680 ? CalleeInfo::HotnessType::Cold
681 : CalleeInfo::HotnessType::Critical);
690 const auto *CB = dyn_cast<CallBase>(&
I);
694 if (CallsThatMayHaveMemprofSummary.
count(CB))
703 bool NotEligibleForImport =
704 NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
705 HasIndirBranchToBlockAddress || HasLocalIFuncCallOrRef;
707 F.getLinkage(),
F.getVisibility(), NotEligibleForImport,
708 false,
F.isDSOLocal(),
F.canBeOmittedFromSymbolTable(),
709 GlobalValueSummary::ImportKind::Definition);
711 F.doesNotAccessMemory(),
F.onlyReadsMemory() && !
F.doesNotAccessMemory(),
712 F.hasFnAttribute(Attribute::NoRecurse),
F.returnDoesNotAlias(),
715 F.getAttributes().hasFnAttr(Attribute::NoInline),
716 F.hasFnAttribute(Attribute::AlwaysInline),
717 F.hasFnAttribute(Attribute::NoUnwind), MayThrow, HasUnknownCall,
719 std::vector<FunctionSummary::ParamAccess> ParamAccesses;
720 if (
auto *SSI = GetSSICallback(
F))
721 ParamAccesses = SSI->getParamAccesses(Index);
722 auto FuncSummary = std::make_unique<FunctionSummary>(
723 Flags, NumInsts, FunFlags, std::move(Refs), CallGraphEdges.
takeVector(),
726 TypeTestAssumeConstVCalls.takeVector(),
727 TypeCheckedLoadConstVCalls.takeVector(), std::move(ParamAccesses),
728 std::move(Callsites), std::move(Allocs));
729 if (NonRenamableLocal)
730 CantBePromoted.
insert(
F.getGUID());
731 Index.addGlobalValueSummary(
F, std::move(FuncSummary));
744 if (
I->getType()->isPointerTy()) {
745 auto C =
I->stripPointerCasts();
746 auto A = dyn_cast<GlobalAlias>(
C);
747 if (isa<Function>(
C) || (
A && isa<Function>(
A->getAliasee()))) {
748 auto GV = dyn_cast<GlobalValue>(
C);
752 if (GV && GV->getName() !=
"__cxa_pure_virtual")
753 VTableFuncs.push_back({Index.getOrInsertValueInfo(GV), StartingOffset});
761 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
762 StructType *STy = dyn_cast<StructType>(
C->getType());
770 StartingOffset +
Offset, M, Index, VTableFuncs, OrigGV);
772 }
else if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
774 Type *EltTy = ATy->getElementType();
775 uint64_t EltSize =
DL.getTypeAllocSize(EltTy);
776 for (
unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
778 StartingOffset + i * EltSize, M, Index, VTableFuncs,
781 }
else if (
const auto *CE = dyn_cast<ConstantExpr>(
I)) {
783 if (CE->getOpcode() != Instruction::Trunc ||
784 !(CE = dyn_cast<ConstantExpr>(CE->getOperand(0))))
790 if (CE->getOpcode() == Instruction::Sub) {
792 APSInt LHSOffset, RHSOffset;
823 for (
auto &
P : VTableFuncs) {
827 assert(
P.VTableOffset >= PrevOffset);
828 PrevOffset =
P.VTableOffset;
843 cast<ConstantAsMetadata>(
Type->getOperand(0))->getValue())
846 if (
auto *TypeId = dyn_cast<MDString>(
TypeID))
847 Index.getOrInsertTypeIdCompatibleVtableSummary(TypeId->getString())
848 .push_back({
Offset, Index.getOrInsertValueInfo(&V)});
859 bool RefLocalIFunc =
false;
860 bool HasBlockAddress =
861 findRefEdges(Index, &V, RefEdges, Visited, RefLocalIFunc);
862 const bool NotEligibleForImport = (HasBlockAddress || RefLocalIFunc);
865 V.getLinkage(), V.getVisibility(), NonRenamableLocal,
866 false, V.isDSOLocal(), V.canBeOmittedFromSymbolTable(),
872 if (!Index.enableSplitLTOUnit()) {
874 V.getMetadata(LLVMContext::MD_type, Types);
875 if (!Types.empty()) {
885 bool CanBeInternalized =
886 !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() &&
887 !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass();
890 Constant ?
false : CanBeInternalized,
892 auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags,
894 if (NonRenamableLocal)
895 CantBePromoted.
insert(V.getGUID());
896 if (NotEligibleForImport)
897 GVarSummary->setNotEligibleToImport();
898 if (!VTableFuncs.empty())
899 GVarSummary->setVTableFuncs(VTableFuncs);
900 Index.addGlobalValueSummary(V, std::move(GVarSummary));
908 if (isa<GlobalIFunc>(Aliasee))
912 A.getLinkage(),
A.getVisibility(), NonRenamableLocal,
913 false,
A.isDSOLocal(),
A.canBeOmittedFromSymbolTable(),
915 auto AS = std::make_unique<AliasSummary>(Flags);
916 auto AliaseeVI = Index.getValueInfo(Aliasee->
getGUID());
917 assert(AliaseeVI &&
"Alias expects aliasee summary to be available");
918 assert(AliaseeVI.getSummaryList().size() == 1 &&
919 "Expected a single entry per aliasee in per-module index");
920 AS->setAliasee(AliaseeVI, AliaseeVI.getSummaryList()[0].get());
921 if (NonRenamableLocal)
922 CantBePromoted.
insert(
A.getGUID());
923 Index.addGlobalValueSummary(
A, std::move(AS));
930 for (
const auto &Summary : VI.getSummaryList())
931 Summary->setLive(
true);
940 bool EnableSplitLTOUnit =
false;
941 bool UnifiedLTO =
false;
942 if (
auto *MD = mdconst::extract_or_null<ConstantInt>(
943 M.getModuleFlag(
"EnableSplitLTOUnit")))
944 EnableSplitLTOUnit = MD->getZExtValue();
946 mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(
"UnifiedLTO")))
947 UnifiedLTO = MD->getZExtValue();
962 for (
auto *V : Used) {
963 if (V->hasLocalLinkage()) {
965 CantBePromoted.
insert(V->getGUID());
969 bool HasLocalInlineAsmSymbol =
false;
970 if (!M.getModuleInlineAsm().empty()) {
986 HasLocalInlineAsmSymbol =
true;
999 if (
Function *
F = dyn_cast<Function>(GV)) {
1000 std::unique_ptr<FunctionSummary> Summary =
1001 std::make_unique<FunctionSummary>(
1004 F->hasFnAttribute(Attribute::ReadNone),
1005 F->hasFnAttribute(Attribute::ReadOnly),
1006 F->hasFnAttribute(Attribute::NoRecurse),
1007 F->returnDoesNotAlias(),
1009 F->hasFnAttribute(Attribute::AlwaysInline),
1010 F->hasFnAttribute(Attribute::NoUnwind),
1023 Index.addGlobalValueSummary(*GV, std::move(Summary));
1025 std::unique_ptr<GlobalVarSummary> Summary =
1026 std::make_unique<GlobalVarSummary>(
1029 false,
false, cast<GlobalVariable>(GV)->
isConstant(),
1032 Index.addGlobalValueSummary(*GV, std::move(Summary));
1037 bool IsThinLTO =
true;
1039 mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(
"ThinLTO")))
1040 IsThinLTO = MD->getZExtValue();
1044 for (
const auto &
F : M) {
1045 if (
F.isDeclaration())
1050 std::unique_ptr<BlockFrequencyInfo> BFIPtr;
1052 BFI = GetBFICallback(
F);
1053 else if (
F.hasProfileData()) {
1056 BFIPtr = std::make_unique<BlockFrequencyInfo>(
F, BPI, LI);
1061 !LocalsUsed.
empty() || HasLocalInlineAsmSymbol,
1062 CantBePromoted, IsThinLTO, GetSSICallback);
1069 if (
G.isDeclaration())
1081 I.applyAlongResolverPath([&Index](
const GlobalValue &GV) {
1082 Index.getGlobalValueSummary(GV)->setLive(
true);
1086 for (
auto *V : LocalsUsed) {
1087 auto *Summary = Index.getGlobalValueSummary(*V);
1088 assert(Summary &&
"Missing summary for global value");
1089 Summary->setNotEligibleToImport();
1101 for (
auto &GlobalList : Index) {
1103 if (GlobalList.second.SummaryList.empty())
1106 assert(GlobalList.second.SummaryList.size() == 1 &&
1107 "Expected module's index to have one summary per GUID");
1108 auto &Summary = GlobalList.second.SummaryList[0];
1110 Summary->setNotEligibleToImport();
1114 bool AllRefsCanBeExternallyReferenced =
1116 return !CantBePromoted.count(VI.getGUID());
1118 if (!AllRefsCanBeExternallyReferenced) {
1119 Summary->setNotEligibleToImport();
1123 if (
auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
1126 return !CantBePromoted.count(Edge.first.getGUID());
1128 if (!AllCallsCanBeExternallyReferenced)
1129 Summary->setNotEligibleToImport();
1139 Index.exportToDot(OSDot, {});
1169 "Module Summary Analysis",
false,
true)
1184 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
1189 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
1195 return NeedSSI ? &getAnalysis<StackSafetyInfoWrapperPass>(
1232 "Module summary info",
false,
true)
1237 if (CB->isDebugOrPseudoInst())
1239 auto *CI = dyn_cast<CallInst>(CB);
1240 auto *CalledValue = CB->getCalledOperand();
1241 auto *CalledFunction = CB->getCalledFunction();
1242 if (CalledValue && !CalledFunction) {
1243 CalledValue = CalledValue->stripPointerCasts();
1245 CalledFunction = dyn_cast<Function>(CalledValue);
1249 if (
auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
1250 assert(!CalledFunction &&
1251 "Expected null called function in callsite for alias");
1252 CalledFunction = dyn_cast<Function>(GA->getAliaseeObject());
1256 if (CalledFunction) {
1257 if (CI && CalledFunction->isIntrinsic())
1264 if (CI && CI->isInlineAsm())
1267 if (!CalledValue || isa<Constant>(CalledValue))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
block Block Frequency Analysis
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseSet and SmallDenseSet classes.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
This file implements a map that provides insertion order iteration.
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)
static cl::opt< bool > EnableMemProfIndirectCallSupport("enable-memprof-indirect-call-support", cl::init(true), cl::Hidden, cl::desc("Enable MemProf support for summarizing and cloning indirect calls"))
cl::opt< bool > MemProfReportHintedSizes
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)
LLVM_ABI cl::opt< bool > ScalePartialSampleProfileWorkingSetSize
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)
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 bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, SetVector< ValueInfo, SmallVector< ValueInfo, 0 > > &RefEdges, SmallPtrSet< const User *, 8 > &Visited, bool &RefLocalLinkageIFunc)
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...
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
An arbitrary precision integer that knows its signedness.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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),...
LLVM Basic Block Representation.
static LLVM_ABI BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
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...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Implements a dense probed hash-table based set.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
std::pair< ValueInfo, CalleeInfo > EdgeTy
<CalleeValueInfo, CalleeInfo> call edge pair.
ForceSummaryHotnessType
Types for -force-summary-edges-cold debugging option.
Class to represent profile counts.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool hasLocalLinkage() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
@ DefaultVisibility
The GV is visible.
LLVM_ABI bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
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.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType takeVector()
Clear the MapVector and return the underlying vector.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LLVM_ABI 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...
ModuleSummaryIndexWrapperPass()
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 LLVM_ABI 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.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
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.
LLVM_ABI std::optional< uint64_t > getProfileCount(const CallBase &CallInst, BlockFrequencyInfo *BFI, bool AllowSynthetic=false) const
Returns the profile count for CallInst.
LLVM_ABI bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
LLVM_ABI bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
A vector that has set insertion semantics.
bool remove(const value_type &X)
Remove an item from the set vector.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
LLVM_ABI unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
ArrayRef< Type * > elements() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
TypeID
Definitions of all of the base types for the Type system.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
iterator_range< use_iterator > uses()
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
CallStackIterator beginAfterSharedPrefix(const CallStack &Other)
CallStackIterator end() const
A raw_ostream that writes to a file descriptor.
@ C
The default llvm calling convention, compatible with C.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
LLVM_ABI bool metadataIncludesAllContextSizeInfo()
Whether the alloc memeprof metadata will include context size info for all MIBs.
LLVM_ABI AllocationType getMIBAllocType(const MDNode *MIB)
Returns the allocation type from an MIB metadata node.
LLVM_ABI MDNode * getMIBStackNode(const MDNode *MIB)
Returns the stack node from an MIB metadata node.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI bool mayHaveMemprofSummary(const CallBase *CB)
Returns true if the instruction could have memprof metadata, used to ensure consistency between summa...
LLVM_ABI 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.
FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold
bool needsParamAccessSummary(const Module &M)
LLVM_ABI 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.
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.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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...
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
LLVM_ABI ModulePass * createModuleSummaryIndexWrapperPass()
LLVM_ABI ImmutablePass * createImmutableModuleSummaryIndexWrapperPass(const ModuleSummaryIndex *Index)
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 ...
LLVM_ABI 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 ...
Summary of memprof metadata on allocations.
A special type used by analysis passes to provide an address that identifies that particular analysis...
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.