73#define DEBUG_TYPE "function-attrs"
75STATISTIC(NumMemoryAttr,
"Number of functions with improved memory attribute");
76STATISTIC(NumCapturesNone,
"Number of arguments marked captures(none)");
77STATISTIC(NumCapturesPartial,
"Number of arguments marked with captures "
78 "attribute other than captures(none)");
79STATISTIC(NumReturned,
"Number of arguments marked returned");
80STATISTIC(NumReadNoneArg,
"Number of arguments marked readnone");
81STATISTIC(NumReadOnlyArg,
"Number of arguments marked readonly");
82STATISTIC(NumWriteOnlyArg,
"Number of arguments marked writeonly");
83STATISTIC(NumNoAlias,
"Number of function returns marked noalias");
84STATISTIC(NumNonNullReturn,
"Number of function returns marked nonnull");
85STATISTIC(NumNoUndefReturn,
"Number of function returns marked noundef");
86STATISTIC(NumNoRecurse,
"Number of functions marked as norecurse");
87STATISTIC(NumNoUnwind,
"Number of functions marked as nounwind");
88STATISTIC(NumNoFree,
"Number of functions marked as nofree");
89STATISTIC(NumNoFreeArg,
"Number of arguments marked as nofree");
90STATISTIC(NumWillReturn,
"Number of functions marked as willreturn");
91STATISTIC(NumNoSync,
"Number of functions marked as nosync");
92STATISTIC(NumCold,
"Number of functions marked as cold");
95 "Number of functions marked as norecurse during thinlink");
97 "Number of functions marked as nounwind during thinlink");
101 cl::desc(
"Don't propagate function-attrs in thinLTO"));
107 ++NumCapturesPartial;
141 if (!Arg->getType()->isPtrOrPtrVectorTy())
162static std::pair<MemoryEffects, MemoryEffects>
164 const SCCNodeSet &SCCNodes) {
190 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||
191 F.getAttributes().hasAttrSomewhere(Attribute::Preallocated))
204 if (
Call && !
Call->hasOperandBundles() &&
Call->getCalledFunction() &&
205 SCCNodes.count(
Call->getCalledFunction())) {
213 if ((ME & OrigME) == OrigME)
230 AddNonArgMemoryEffects(CallME);
252 AddNonArgMemoryEffects(InstME);
256 return {OrigME & ME, RecursiveArgME};
265template <
typename AARGetterT>
276 auto [FnME, FnRecursiveArgME] =
279 RecursiveArgME |= FnRecursiveArgME;
293 if (NewME != OldME) {
295 F->setMemoryEffects(NewME);
299 A.removeAttr(Attribute::Writable);
313 auto [It, Inserted] = CachedPrevailingSummary.
try_emplace(VI);
360 for (
const auto &GVS : VI.getSummaryList()) {
366 if (!FS || FS->fflags().HasUnknownCall)
369 const auto &
Linkage = GVS->linkage();
374 <<
"ThinLTO FunctionAttrs: Multiple Local Linkage, bailing on "
376 << VI.name() <<
" from " << FS->modulePath() <<
". Previous module "
377 <<
Local->modulePath() <<
"\n");
382 assert(IsPrevailing(VI.getGUID(), GVS.get()) || GVS->wasPromoted());
389 if (IsPrevailing(VI.getGUID(), GVS.get())) {
399 auto &CPS = CachedPrevailingSummary[VI];
403 }
else if (Prevailing) {
423 auto PropagateAttributes = [&](std::vector<ValueInfo> &SCCNodes) {
426 InferredFlags.
NoRecurse = (SCCNodes.size() == 1);
429 for (
auto &V : SCCNodes) {
440 for (
const auto &Callee : CallerSummary->
calls()) {
442 Callee.first, CachedPrevailingSummary, IsPrevailing);
460 for (
auto &V : SCCNodes) {
462 LLVM_DEBUG(
dbgs() <<
"ThinLTO FunctionAttrs: Propagated NoRecurse to "
463 << V.name() <<
"\n");
464 ++NumThinLinkNoRecurse;
468 LLVM_DEBUG(
dbgs() <<
"ThinLTO FunctionAttrs: Propagated NoUnwind to "
469 << V.name() <<
"\n");
470 ++NumThinLinkNoUnwind;
473 for (
const auto &S : V.getSummaryList()) {
489 std::vector<ValueInfo> Nodes(*
I);
490 PropagateAttributes(Nodes);
500struct ArgumentGraphNode {
511 using ArgumentMapTy = std::map<Argument *, ArgumentGraphNode>;
513 ArgumentMapTy ArgumentMap;
521 ArgumentGraphNode SyntheticRoot;
524 ArgumentGraph() { SyntheticRoot.Definition =
nullptr; }
528 iterator
begin() {
return SyntheticRoot.Uses.begin(); }
529 iterator
end() {
return SyntheticRoot.Uses.end(); }
530 ArgumentGraphNode *getEntryNode() {
return &SyntheticRoot; }
532 ArgumentGraphNode *operator[](Argument *
A) {
533 ArgumentGraphNode &
Node = ArgumentMap[
A];
535 SyntheticRoot.Uses.push_back(&Node);
544 ArgumentUsesTracker(
const SCCNodeSet &SCCNodes) : SCCNodes(SCCNodes) {}
548 Action captured(
const Use *U, UseCaptureInfo UseCI)
override {
549 if (updateCaptureInfo(U, UseCI.
UseCC)) {
558 return ContinueIgnoringReturn;
569 CI |= CaptureInfo(
CC);
574 if (!
F || !
F->hasExactDefinition() || !SCCNodes.count(
F)) {
575 CI |= CaptureInfo(
CC);
589 CI |= CaptureInfo(
CC);
593 if (UseIndex >=
F->arg_size()) {
594 assert(
F->isVarArg() &&
"More params than args in non-varargs call");
595 CI |= CaptureInfo(
CC);
601 Uses.push_back(&*std::next(
F->arg_begin(), UseIndex));
611 const SCCNodeSet &SCCNodes;
619 std::optional<int64_t> Offset;
626struct ArgumentAccessInfo {
627 enum class AccessType : uint8_t {
Write, WriteWithSideEffect,
Read,
Unknown };
628 AccessType ArgAccessType;
629 ConstantRangeList AccessRanges;
633struct UsesPerBlockInfo {
634 SmallDenseMap<Instruction *, ArgumentAccessInfo, 4> Insts;
635 bool HasWrites =
false;
636 bool HasUnknownAccess =
false;
640struct ArgumentUsesSummary {
641 bool HasAnyWrite =
false;
642 bool HasWriteOutsideEntryBB =
false;
643 SmallDenseMap<const BasicBlock *, UsesPerBlockInfo, 16> UsesPerBlock;
646ArgumentAccessInfo getArgumentAccessInfo(
const Instruction *
I,
647 const ArgumentUse &ArgUse,
649 auto GetTypeAccessRange =
651 std::optional<int64_t>
Offset) -> std::optional<ConstantRange> {
665 auto GetConstantIntRange =
667 std::optional<int64_t>
Offset) -> std::optional<ConstantRange> {
669 if (ConstantLength &&
Offset) {
670 int64_t
Len = ConstantLength->getSExtValue();
688 if (
SI->isSimple() && &
SI->getOperandUse(1) == ArgUse.U) {
693 if (
auto TypeAccessRange =
694 GetTypeAccessRange(
SI->getAccessType(), ArgUse.Offset))
695 AccessRanges.
insert(*TypeAccessRange);
696 return {ArgumentAccessInfo::AccessType::Write, std::move(AccessRanges)};
699 if (LI->isSimple()) {
700 assert(&LI->getOperandUse(0) == ArgUse.U);
704 if (
auto TypeAccessRange =
705 GetTypeAccessRange(LI->getAccessType(), ArgUse.Offset))
706 return {ArgumentAccessInfo::AccessType::Read, {*TypeAccessRange}};
709 if (!MemSet->isVolatile()) {
711 if (
auto AccessRange =
712 GetConstantIntRange(MemSet->getLength(), ArgUse.Offset))
713 AccessRanges.
insert(*AccessRange);
714 return {ArgumentAccessInfo::AccessType::Write, AccessRanges};
717 if (!MTI->isVolatile()) {
718 if (&MTI->getOperandUse(0) == ArgUse.U) {
720 if (
auto AccessRange =
721 GetConstantIntRange(MTI->getLength(), ArgUse.Offset))
722 AccessRanges.
insert(*AccessRange);
723 return {ArgumentAccessInfo::AccessType::Write, AccessRanges};
724 }
else if (&MTI->getOperandUse(1) == ArgUse.U) {
725 if (
auto AccessRange =
726 GetConstantIntRange(MTI->getLength(), ArgUse.Offset))
727 return {ArgumentAccessInfo::AccessType::Read, {*AccessRange}};
734 bool IsInitialize = CB->
paramHasAttr(ArgNo, Attribute::Initializes);
735 if (IsInitialize && ArgUse.Offset) {
739 ? ArgumentAccessInfo::AccessType::Write
740 : ArgumentAccessInfo::AccessType::WriteWithSideEffect;
746 CR.getUpper() + *ArgUse.Offset));
747 return {
Access, AccessRanges};
752 return {ArgumentAccessInfo::AccessType::Unknown, {}};
757 auto &
DL =
F.getDataLayout();
759 DL.getIndexSizeInBits(
A.getType()->getPointerAddressSpace());
760 ArgumentUsesSummary
Result;
764 for (
Use &U :
A.uses())
770 auto *BB =
I->getParent();
771 auto &BBInfo =
Result.UsesPerBlock[BB];
772 auto [It,
Inserted] = BBInfo.Insts.try_emplace(
I);
773 auto &IInfo = It->second;
778 IInfo = {ArgumentAccessInfo::AccessType::Unknown, {}};
779 BBInfo.HasUnknownAccess =
true;
783 IInfo = std::move(Info);
784 BBInfo.HasUnknownAccess |=
785 IInfo.ArgAccessType == ArgumentAccessInfo::AccessType::Unknown;
787 (IInfo.ArgAccessType == ArgumentAccessInfo::AccessType::Write ||
788 IInfo.ArgAccessType ==
789 ArgumentAccessInfo::AccessType::WriteWithSideEffect) &&
790 !IInfo.AccessRanges.empty();
791 BBInfo.HasWrites |= InfoHasWrites;
792 return InfoHasWrites;
797 while (!Worklist.
empty()) {
799 User *U = ArgUse.U->getUser();
803 std::optional<int64_t> NewOffset = std::nullopt;
807 NewOffset = *ArgUse.Offset +
Offset.getSExtValue();
809 for (
Use &U :
GEP->uses())
815 bool HasWrite = UpdateUseInfo(
I, getArgumentAccessInfo(
I, ArgUse,
DL));
817 Result.HasAnyWrite |= HasWrite;
819 if (HasWrite &&
I->getParent() != &EntryBB)
820 Result.HasWriteOutsideEntryBB =
true;
876 if (
A->hasInAllocaAttr() ||
A->hasPreallocatedAttr())
881 for (
Use &U :
A->uses()) {
886 while (!Worklist.
empty()) {
912 for (
Use &UU :
I->uses())
913 if (Visited.
insert(&UU).second)
934 SCCNodes.
count(
F->getArg(UseIndex)))
957 Props.
IsRead |=
I->mayReadFromMemory();
958 Props.
IsWrite |=
I->mayWriteToMemory();
973 if (!
F->hasExactDefinition())
976 if (
F->getReturnType()->isVoidTy())
980 if (
F->getAttributes().hasAttrSomewhere(Attribute::Returned))
983 auto FindRetArg = [&]() ->
Argument * {
991 if (!RetVal || RetVal->getType() !=
F->getReturnType())
996 else if (RetArg != RetVal)
1003 if (
Argument *RetArg = FindRetArg()) {
1004 RetArg->addAttr(Attribute::Returned);
1016 if (!Opts.enable_poison_arg_attr_prop)
1032 for (
auto &CSArg : CalledFunc->args()) {
1033 unsigned ArgNo = CSArg.getArgNo();
1038 if (CSArg.hasNonNullAttr(
false)) {
1042 if (!FArg->hasNonNullAttr()) {
1043 FArg->addAttr(Attribute::NonNull);
1051 if ((CSNoFPClass | ArgNoFPClass) != ArgNoFPClass) {
1053 FArg->getContext(), CSNoFPClass | ArgNoFPClass));
1068 assert(
A &&
"Argument must not be null.");
1071 if (!Props.
IsFree && !
A->hasAttribute(Attribute::NoFree) &&
1072 !
A->hasAttribute(Attribute::NoFreeObj)) {
1074 A->addAttr(Attribute::NoFree);
1083 Attr = Attribute::ReadOnly;
1085 Attr = Attribute::WriteOnly;
1087 Attr = Attribute::ReadNone;
1090 if (
A->hasAttribute(Attr))
1095 A->removeAttr(Attribute::WriteOnly);
1096 A->removeAttr(Attribute::ReadOnly);
1097 A->removeAttr(Attribute::ReadNone);
1099 if (Attr == Attribute::ReadNone || Attr == Attribute::ReadOnly)
1100 A->removeAttr(Attribute::Writable);
1102 if (Attr == Attribute::ReadOnly)
1104 else if (Attr == Attribute::WriteOnly)
1112 auto ArgumentUses = collectArgumentUsesPerBlock(
A,
F);
1114 if (!ArgumentUses.HasAnyWrite)
1117 auto &UsesPerBlock = ArgumentUses.UsesPerBlock;
1126 auto UPB = UsesPerBlock.find(BB);
1133 if (UPB == UsesPerBlock.end() || !UPB->second.HasUnknownAccess) {
1134 bool HasAddedSuccessor =
false;
1136 if (
auto SuccI = Initialized.
find(Succ); SuccI != Initialized.
end()) {
1137 if (HasAddedSuccessor) {
1140 CRL = SuccI->second;
1141 HasAddedSuccessor =
true;
1150 if (UPB != UsesPerBlock.end()) {
1154 sort(Insts, [](std::pair<Instruction *, ArgumentAccessInfo> &
LHS,
1155 std::pair<Instruction *, ArgumentAccessInfo> &
RHS) {
1156 return LHS.first->comesBefore(
RHS.first);
1161 for (
auto &[
_, Info] :
reverse(Insts)) {
1162 if (Info.ArgAccessType == ArgumentAccessInfo::AccessType::Unknown ||
1163 Info.ArgAccessType ==
1164 ArgumentAccessInfo::AccessType::WriteWithSideEffect)
1166 if (!Info.AccessRanges.empty()) {
1167 if (Info.ArgAccessType == ArgumentAccessInfo::AccessType::Write ||
1168 Info.ArgAccessType ==
1169 ArgumentAccessInfo::AccessType::WriteWithSideEffect) {
1172 assert(Info.ArgAccessType == ArgumentAccessInfo::AccessType::Read);
1173 for (
const auto &ReadRange : Info.AccessRanges)
1185 bool OnlyScanEntryBlock = !ArgumentUses.HasWriteOutsideEntryBB;
1186 if (!OnlyScanEntryBlock)
1187 if (
auto EntryUPB = UsesPerBlock.find(&EntryBB);
1188 EntryUPB != UsesPerBlock.end())
1189 OnlyScanEntryBlock = EntryUPB->second.HasUnknownAccess;
1190 if (OnlyScanEntryBlock) {
1191 EntryCRL = VisitBlock(&EntryBB);
1192 if (EntryCRL.
empty())
1203 Initialized[BB] = CRL;
1206 auto EntryCRLI = Initialized.
find(&EntryBB);
1207 if (EntryCRLI == Initialized.
end())
1210 EntryCRL = EntryCRLI->second;
1214 "should have bailed already if EntryCRL is empty");
1216 if (
A.hasAttribute(Attribute::Initializes)) {
1218 A.getAttribute(Attribute::Initializes).getValueAsConstantRangeList();
1219 if (PreviousCRL == EntryCRL)
1221 EntryCRL = EntryCRL.
unionWith(PreviousCRL);
1233 bool SkipInitializes) {
1236 auto DetermineAccessAttrsForSingleton = [](
Argument *
A) {
1248 if (!
F->hasExactDefinition())
1256 if (
F->onlyReadsMemory() &&
F->doesNotThrow() &&
F->willReturn() &&
1257 F->getReturnType()->isVoidTy()) {
1259 if (
A.getType()->isPointerTy() && !
A.hasNoCaptureAttr()) {
1270 if (!
A.getType()->isPointerTy())
1272 bool HasNonLocalUses =
false;
1273 CaptureInfo OrigCI =
A.getAttributes().getCaptureInfo();
1275 ArgumentUsesTracker Tracker(SCCNodes);
1278 if (NewCI != OrigCI) {
1279 if (Tracker.Uses.empty()) {
1288 ArgumentGraphNode *
Node = AG[&
A];
1291 Node->Uses.push_back(AG[
Use]);
1293 HasNonLocalUses =
true;
1299 if (!HasNonLocalUses && !
A.onlyReadsMemory()) {
1304 if (DetermineAccessAttrsForSingleton(&
A))
1307 if (!SkipInitializes && !
A.onlyReadsMemory()) {
1322 const std::vector<ArgumentGraphNode *> &ArgumentSCC = *
I;
1323 if (ArgumentSCC.size() == 1) {
1324 if (!ArgumentSCC[0]->Definition)
1328 if (ArgumentSCC[0]->
Uses.size() == 1 &&
1329 ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
1330 Argument *
A = ArgumentSCC[0]->Definition;
1331 CaptureInfo OrigCI =
A->getAttributes().getCaptureInfo();
1333 if (NewCI != OrigCI) {
1340 if (DetermineAccessAttrsForSingleton(
A))
1349 for (ArgumentGraphNode *
I : ArgumentSCC) {
1350 ArgumentSCCNodes.
insert(
I->Definition);
1357 for (ArgumentGraphNode *
N : ArgumentSCC) {
1358 for (ArgumentGraphNode *
Use :
N->Uses) {
1360 if (ArgumentSCCNodes.
count(
A))
1370 for (ArgumentGraphNode *
N : ArgumentSCC) {
1372 CaptureInfo OrigCI =
A->getAttributes().getCaptureInfo();
1374 if (NewCI != OrigCI) {
1385 for (ArgumentGraphNode *
N : ArgumentSCC) {
1386 if (DetermineAccessAttrsForSingleton(
N->Definition))
1387 Changed.insert(
N->Definition->getParent());
1404 for (ArgumentGraphNode *
N : ArgumentSCC) {
1412 for (ArgumentGraphNode *
N : ArgumentSCC) {
1429 FlowsToReturn.
insert(Ret->getReturnValue());
1431 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
1432 Value *RetVal = FlowsToReturn[i];
1445 switch (RVI->getOpcode()) {
1447 case Instruction::BitCast:
1448 case Instruction::GetElementPtr:
1449 case Instruction::AddrSpaceCast:
1450 FlowsToReturn.
insert(RVI->getOperand(0));
1452 case Instruction::Select: {
1454 FlowsToReturn.
insert(
SI->getTrueValue());
1455 FlowsToReturn.
insert(
SI->getFalseValue());
1458 case Instruction::PHI: {
1465 case Instruction::Alloca:
1467 case Instruction::Call:
1468 case Instruction::Invoke: {
1498 if (
F->returnDoesNotAlias())
1504 if (!
F->hasExactDefinition())
1509 if (!
F->getReturnType()->isPointerTy())
1517 if (
F->returnDoesNotAlias() ||
1518 !
F->getReturnType()->isPointerTy())
1521 F->setReturnDoesNotAlias();
1535 bool &Speculative) {
1536 assert(
F->getReturnType()->isPointerTy() &&
1537 "nonnull only meaningful on pointer types");
1538 Speculative =
false;
1543 FlowsToReturn.
insert(Ret->getReturnValue());
1545 auto &
DL =
F->getDataLayout();
1547 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
1548 Value *RetVal = FlowsToReturn[i];
1561 case Instruction::BitCast:
1562 case Instruction::AddrSpaceCast:
1565 case Instruction::GetElementPtr:
1571 case Instruction::Select: {
1573 FlowsToReturn.
insert(
SI->getTrueValue());
1574 FlowsToReturn.
insert(
SI->getFalseValue());
1577 case Instruction::PHI: {
1583 case Instruction::Call:
1584 case Instruction::Invoke: {
1589 if (Callee && SCCNodes.count(Callee)) {
1609 bool SCCReturnsNonNull =
true;
1615 if (
F->getAttributes().hasRetAttr(Attribute::NonNull))
1621 if (!
F->hasExactDefinition())
1626 if (!
F->getReturnType()->isPointerTy())
1629 bool Speculative =
false;
1635 <<
" as nonnull\n");
1636 F->addRetAttr(Attribute::NonNull);
1644 SCCReturnsNonNull =
false;
1647 if (SCCReturnsNonNull) {
1649 if (
F->getAttributes().hasRetAttr(Attribute::NonNull) ||
1650 !
F->getReturnType()->isPointerTy())
1653 LLVM_DEBUG(
dbgs() <<
"SCC marking " <<
F->getName() <<
" as nonnull\n");
1654 F->addRetAttr(Attribute::NonNull);
1669 if (Attrs.hasRetAttr(Attribute::NoUndef))
1675 if (!
F->hasExactDefinition())
1681 if (
F->hasFnAttribute(Attribute::SanitizeMemory))
1684 if (
F->getReturnType()->isVoidTy())
1691 Value *RetVal = Ret->getReturnValue();
1698 if (Attrs.hasRetAttr(Attribute::NonNull) &&
1706 Attribute Attr = Attrs.getRetAttr(Attribute::Range);
1713 FPClassTest AttrFPClass = Attrs.getRetNoFPClass();
1714 if (AttrFPClass !=
fcNone) {
1722 F->addRetAttr(Attribute::NoUndef);
1737class AttributeInferer {
1740 struct InferenceDescriptor {
1746 std::function<bool(
const Function &)> SkipFunction;
1749 std::function<bool(Instruction &)> InstrBreaksAttribute;
1752 std::function<void(
Function &)> SetAttribute;
1755 Attribute::AttrKind AKind;
1759 bool RequiresExactDefinition;
1761 InferenceDescriptor(Attribute::AttrKind AK,
1762 std::function<
bool(
const Function &)> SkipFunc,
1763 std::function<
bool(Instruction &)> InstrScan,
1764 std::function<
void(
Function &)> SetAttr,
1766 : SkipFunction(SkipFunc), InstrBreaksAttribute(InstrScan),
1767 SetAttribute(SetAttr), AKind(AK),
1768 RequiresExactDefinition(ReqExactDef) {}
1775 void registerAttrInference(InferenceDescriptor AttrInference) {
1776 InferenceDescriptors.push_back(AttrInference);
1779 void run(
const SCCNodeSet &SCCNodes, SmallPtrSet<Function *, 8> &
Changed);
1784void AttributeInferer::run(
const SCCNodeSet &SCCNodes,
1793 if (InferInSCC.
empty())
1798 if (
ID.SkipFunction(*
F))
1803 return F->isDeclaration() ||
1804 (
ID.RequiresExactDefinition && !
F->hasExactDefinition());
1811 InferInSCC, std::back_inserter(InferInThisFunc),
1812 [
F](
const InferenceDescriptor &ID) {
return !
ID.SkipFunction(*
F); });
1814 if (InferInThisFunc.empty())
1819 llvm::erase_if(InferInThisFunc, [&](
const InferenceDescriptor &ID) {
1820 if (!
ID.InstrBreaksAttribute(
I))
1825 return D.AKind ==
ID.AKind;
1831 if (InferInThisFunc.empty())
1836 if (InferInSCC.
empty())
1844 for (
auto &ID : InferInSCC) {
1845 if (
ID.SkipFunction(*
F))
1848 ID.SetAttribute(*
F);
1852struct SCCNodesResult {
1853 SCCNodeSet SCCNodes;
1860 const SCCNodeSet &SCCNodes) {
1870 if (!
I.mayThrow(
true))
1873 if (
Function *Callee = CI->getCalledFunction()) {
1877 if (SCCNodes.contains(Callee))
1890 return I.maySynchronize();
1898 if (SCCNodes.contains(Callee))
1905 if (!
I.maySynchronize())
1912 if (SCCNodes.contains(Callee))
1923 AttributeInferer AI;
1930 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1931 Attribute::Convergent,
1933 [](
const Function &
F) {
return !
F.isConvergent(); },
1939 LLVM_DEBUG(
dbgs() <<
"Removing convergent attr from fn " <<
F.getName()
1941 F.setNotConvergent();
1953 const SCCNodeSet &SCCNodes,
1955 AttributeInferer AI;
1957 if (Opts.nounwind_inference)
1963 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1964 Attribute::NoUnwind,
1966 [](
const Function &
F) {
return F.doesNotThrow(); },
1973 <<
"Adding nounwind attr to fn " <<
F.getName() <<
"\n");
1974 F.setDoesNotThrow();
1979 if (Opts.nofree_inference)
1986 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1989 [](
const Function &
F) {
return F.doesNotFreeMemory(); },
1996 <<
"Adding nofree attr to fn " <<
F.getName() <<
"\n");
1997 F.setDoesNotFreeMemory();
2002 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
2005 [](
const Function &
F) {
return F.hasNoSync(); },
2012 <<
"Adding nosync attr to fn " <<
F.getName() <<
"\n");
2030 bool AnyFunctionsAddressIsTaken =
true) {
2031 for (
const auto &BB :
F) {
2032 for (
const auto &
I : BB) {
2035 if (!Callee || Callee == &
F)
2038 if (Callee->doesNotRecurse())
2041 if (!AnyFunctionsAddressIsTaken ||
2042 (Callee->isDeclaration() &&
2043 Callee->hasFnAttribute(Attribute::NoCallback)))
2057 if (SCCNodes.size() != 1)
2061 if (!
F || !
F->hasExactDefinition() ||
F->doesNotRecurse())
2067 F->setDoesNotRecurse();
2077 if (!
F || !
F->hasExactDefinition() ||
F->hasFnAttribute(Attribute::Naked) ||
2082 F->setDoesNotReturn();
2090 ColdPaths[&
F.front()] =
false;
2094 while (!Jobs.
empty()) {
2105 ColdPaths[BB] =
true;
2122 auto [Iter, Inserted] = ColdPaths.
try_emplace(Succ,
false);
2138 if (!
F || !
F->hasExactDefinition() ||
F->hasFnAttribute(Attribute::Naked) ||
2139 F->hasFnAttribute(Attribute::Cold) ||
F->hasFnAttribute(Attribute::Hot))
2144 F->addFnAttr(Attribute::Cold);
2156 if (!
F.hasExactDefinition())
2160 if (
F.mustProgress() &&
F.onlyReadsMemory())
2164 if (
F.isDeclaration())
2171 if (!Backedges.
empty())
2177 return I.willReturn();
2197 if (!
F ||
F->hasOptNone() ||
F->hasFnAttribute(Attribute::Naked) ||
2198 F->isPresplitCoroutine()) {
2203 Res.SCCNodes.insert(
F);
2208template <
typename AARGetterT>
2209static SmallPtrSet<Function *, 8>
2211 bool ArgAttrsOnly) {
2215 if (Nodes.SCCNodes.empty())
2218 const IPOOptions &Opts =
getIPOOptions(*Nodes.SCCNodes.front());
2260 bool ArgAttrsOnly =
false;
2261 if (
C.size() == 1 && SkipNonRecursive) {
2264 ArgAttrsOnly =
true;
2278 Functions.push_back(&
N.getFunction());
2281 auto ChangedFunctions =
2283 if (ChangedFunctions.empty())
2297 for (
auto *U :
Changed->users()) {
2300 FAM.invalidate(*
Call->getFunction(), FuncPA);
2315 static_cast<PassInfoMixin<PostOrderFunctionAttrsPass> *
>(
this)->
printPipeline(
2316 OS, MapClassName2PassName);
2317 if (SkipNonRecursive)
2318 OS <<
"<skip-non-recursive-function-attrs>";
2322 if (
F.doesNotRecurse())
2328 assert(!
F.isDeclaration() &&
"Cannot deduce norecurse without a definition!");
2329 assert(
F.hasInternalLinkage() &&
2330 "Can only do top-down deduction for internal linkage functions!");
2340 for (
auto &U :
F.uses()) {
2343 !CB->
getParent()->getParent()->doesNotRecurse())
2346 F.setDoesNotRecurse();
2352 assert(!
F.isDeclaration() &&
"Cannot deduce nofpclass without a definition!");
2353 unsigned NumArgs =
F.arg_size();
2358 for (
User *U :
F.users()) {
2364 for (
unsigned I = 0;
I != NumArgs; ++
I) {
2369 ArgsNoFPClass[
I] &= ~Cst->classify();
2377 if (RetNoFPClass !=
fcNone) {
2378 FPClassTest OldAttr =
F.getAttributes().getRetNoFPClass();
2379 if (OldAttr != RetNoFPClass) {
2385 for (
unsigned I = 0;
I != NumArgs; ++
I) {
2387 if (ArgNoFPClass ==
fcNone)
2390 if (OldAttr == ArgNoFPClass)
2413 if (SCC.size() != 1)
2415 Function &
F = SCC.begin()->getFunction();
2416 if (!
F.isDeclaration() &&
F.hasInternalLinkage() && !
F.use_empty())
2449 bool AnyFunctionsAddressIsTaken =
false;
2451 if (
F.isDeclaration() ||
F.doesNotRecurse())
2453 if (!
F.hasLocalLinkage() ||
F.hasAddressTaken()) {
2454 AnyFunctionsAddressIsTaken =
true;
2479 if (!
F.hasExactDefinition() ||
F.doesNotRecurse())
2486 F.setDoesNotRecurse();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static SmallPtrSet< Function *, 8 > deriveAttrsInPostOrder(ArrayRef< Function * > Functions, AARGetterT &&AARGetter, bool ArgAttrsOnly)
static void addArgumentAttrs(const IPOOptions &Opts, const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed, bool SkipInitializes)
Deduce nocapture attributes for the SCC.
static bool inferInitializes(Argument &A, Function &F)
static bool allPathsGoThroughCold(Function &F)
static FunctionSummary * calculatePrevailingSummary(ValueInfo VI, DenseMap< ValueInfo, FunctionSummary * > &CachedPrevailingSummary, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing)
static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, SmallPtrSet< Function *, 8 > &Changed)
Deduce readonly/readnone/writeonly attributes for the SCC.
static void addCapturesStat(CaptureInfo CI)
static void addArgLocs(MemoryEffects &ME, const CallBase *Call, ModRefInfo ArgMR, AAResults &AAR)
static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes)
Tests whether a function is "malloc-like".
static void addColdAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool addArgumentAttrsFromCallsites(const IPOOptions &Opts, Function &F)
If a callsite has arguments that are also arguments to the parent function, try to propagate attribut...
static bool mayHaveRecursiveCallee(Function &F, bool AnyFunctionsAddressIsTaken=true)
static void addNoReturnAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool addNoFPClassAttrsTopDown(Function &F)
static void addWillReturn(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static void inferAttrsFromFunctionBodies(const IPOOptions &Opts, const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Infer attributes from all functions in the SCC by scanning every instruction for compliance to the at...
static void addNonNullAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce nonnull attributes for the SCC.
static std::pair< MemoryEffects, MemoryEffects > checkFunctionMemoryAccess(Function &F, bool ThisBody, AAResults &AAR, const SCCNodeSet &SCCNodes)
Returns the memory access attribute for function F using AAR for AA results, where SCCNodes is the cu...
static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoUnwind inference predicate InstrBreaksAttribute.
static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes, bool &Speculative)
Tests whether this function is known to not return null.
static bool InstrBreaksNoSync(Instruction &I, const SCCNodeSet &SCCNodes)
static bool deduceFunctionAttributeInRPO(Module &M, LazyCallGraph &CG)
static ArgAccessProperties determinePointerAccessAttrs(Argument *A, const SmallPtrSet< Argument *, 8 > &SCCNodes)
Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoFree inference predicate InstrBreaksAttribute.
static bool addAccessAttrs(Argument *A, ArgAccessProperties Props)
static void addNoAliasAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noalias attributes for the SCC.
static bool addNoRecurseAttrsTopDown(Function &F)
static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc, ModRefInfo MR, AAResults &AAR)
static void inferConvergent(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Attempt to remove convergent function attribute when possible.
static cl::opt< bool > DisableThinLTOPropagation("disable-thinlto-funcattrs", cl::init(true), cl::Hidden, cl::desc("Don't propagate function-attrs in thinLTO"))
static SCCNodesResult createSCCNodeSet(ArrayRef< Function * > Functions)
static bool InstrBreaksNonConvergent(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for non-Convergent inference predicate InstrBreaksAttribute.
static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool functionWillReturn(const Function &F)
static void addNoUndefAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noundef attributes for the SCC.
static void addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce returned attributes for the SCC.
Provides passes for computing function attributes based on interprocedural analyses.
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
Implements a lazy call graph analysis and related passes for the new pass manager.
This file provides utility analysis objects describing memory locations.
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A manager for alias analyses.
LLVM_ABI ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, bool IgnoreLocals=false)
Returns a bitmask that should be unconditionally applied to the ModRef info of a memory location.
LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call)
Return the behavior of the given call site.
Class for arbitrary precision integers.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
bool isValid() const
Return true if the attribute is any kind of attribute.
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI FPClassTest getParamNoFPClass(unsigned i) const
Extract a test mask for disallowed floating-point value classes for the parameter.
LLVM_ABI FPClassTest getRetNoFPClass() const
Extract a test mask for disallowed floating-point value classes for the return value.
LLVM_ABI MemoryEffects getMemoryEffects() const
bool doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
unsigned getDataOperandNo(Value::const_user_iterator UI) const
Given a value use iterator, return the data operand corresponding to it.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Get the attribute of a given kind from a given arg.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
bool onlyWritesMemory(unsigned OpNo) const
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
bool onlyReadsMemory(unsigned OpNo) const
Value * getArgOperand(unsigned i) const
bool isConvergent() const
Determine if the invoke is convergent.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
bool hasOperandBundles() const
Return true if this User has any operand bundles.
Represents which components of the pointer may be captured in which location.
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
static CaptureInfo retOnly(CaptureComponents RetComponents=CaptureComponents::All)
Create CaptureInfo that may only capture via the return value.
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
This class represents a list of constant ranges.
LLVM_ABI void subtract(const ConstantRange &SubRange)
LLVM_ABI void insert(const ConstantRange &NewRange)
Insert a new range to Ranges and keep the list ordered.
bool empty() const
Return true if this list contains no members.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI ConstantRangeList intersectWith(const ConstantRangeList &CRL) const
Return the range list that results from the intersection of this ConstantRangeList with another Const...
LLVM_ABI ConstantRangeList unionWith(const ConstantRangeList &CRL) const
Return the range list that results from the union of this ConstantRangeList with another ConstantRang...
This class represents a range of values.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
A proxy from a FunctionAnalysisManager to an SCC.
Function summary information to aid decisions and implementation of importing.
ArrayRef< EdgeTy > calls() const
Return the list of <CalleeValueInfo, CalleeInfo> pairs.
FFlags fflags() const
Get function summary flags.
Function and variable summary information to aid decisions and implementation of importing.
static bool isWeakAnyLinkage(LinkageTypes Linkage)
static bool isLinkOnceAnyLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
static bool isWeakODRLinkage(LinkageTypes Linkage)
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
static bool isExternalLinkage(LinkageTypes Linkage)
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isKnownNever(FPClassMask Mask) const
Return true if it's known this can never be one of the mask entries.
This is an important class for using LLVM in a threaded context.
An analysis pass which computes the call graph for a module.
A node in the call graph.
A RefSCC of the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
LLVM_ABI void buildRefSCCs()
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
MemoryEffectsBase getWithoutLoc(Location Loc) const
Get new MemoryEffectsBase with NoModRef on the given Loc.
bool doesNotAccessMemory() const
Whether this function accesses no memory.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
static MemoryEffectsBase none()
static MemoryEffectsBase unknown()
Representation for a specific memory location.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Class to hold module path string table and global value map, and encapsulate methods for operating on...
A Module instance is used to store all the information related to an LLVM module.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
op_range incoming_values()
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Return a value (possibly void), from a function.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
A SetVector that performs no allocations if smaller than a certain size.
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static unsigned getPointerOperandIndex()
Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
constexpr uint64_t PointerSize
aarch64 pointer size.
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
bool capturesReadProvenanceOnly(CaptureComponents CC)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)
Returns the memory access properties of this copy of the function.
@ Unknown
Not known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
LLVM_ABI bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Propagate function attributes for function summaries along the index's callgraph during thinlink.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
const IPOOptions & getIPOOptions(const LLVMContext &C)
auto reverse(ContainerTy &&C)
bool isModSet(const ModRefInfo MRI)
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CaptureComponents
Components of the pointer that may be captured.
LLVM_ABI const Value * getUnderlyingObjectAggressive(const Value *V, bool MustPreserveProvenance=false)
Like getUnderlyingObject(), but will try harder to find a single underlying object.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
bool capturesAnything(CaptureComponents CC)
LLVM_ABI bool inferAttributesFromOthers(Function &F)
If we can infer one attribute from another on the declaration of a function, explicitly materialize t...
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
bool capturesAll(CaptureComponents CC)
bool capturesNothing(CaptureComponents CC)
bool isNoModRef(const ModRefInfo MRI)
LLVM_ABI void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)
Analyze the specified function to find all of the loop backedges in the function and return them.
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool capturesAnyProvenance(CaptureComponents CC)
bool isRefSet(const ModRefInfo MRI)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI bool canReturn(const Function &F)
Return true if there is at least a path through which F can return, false if there is no such path.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static ArgAccessProperties all()
ArgAccessProperties & operator|=(const ArgAccessProperties &Other)
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
This callback is used in conjunction with PointerMayBeCaptured.
Flags specific to function summaries.
SmallVectorImpl< ArgumentGraphNode * >::iterator ChildIteratorType
static ChildIteratorType child_begin(NodeRef N)
static ChildIteratorType child_end(NodeRef N)
ArgumentGraphNode * NodeRef
static NodeRef getEntryNode(NodeRef A)
static ChildIteratorType nodes_end(ArgumentGraph *AG)
static NodeRef getEntryNode(ArgumentGraph *AG)
static ChildIteratorType nodes_begin(ArgumentGraph *AG)
typename ArgumentGraph *::UnknownGraphTypeError NodeRef
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Capture information for a specific Use.
CaptureComponents UseCC
Components captured by this use.
Struct that holds a reference to a particular GUID in a global value summary.