65 #define DEBUG_TYPE "functionattrs" 67 STATISTIC(NumReadNone,
"Number of functions marked readnone");
68 STATISTIC(NumReadOnly,
"Number of functions marked readonly");
69 STATISTIC(NumWriteOnly,
"Number of functions marked writeonly");
70 STATISTIC(NumNoCapture,
"Number of arguments marked nocapture");
71 STATISTIC(NumReturned,
"Number of arguments marked returned");
72 STATISTIC(NumReadNoneArg,
"Number of arguments marked readnone");
73 STATISTIC(NumReadOnlyArg,
"Number of arguments marked readonly");
74 STATISTIC(NumNoAlias,
"Number of function returns marked noalias");
75 STATISTIC(NumNonNullReturn,
"Number of function returns marked nonnull");
76 STATISTIC(NumNoRecurse,
"Number of functions marked as norecurse");
77 STATISTIC(NumNoUnwind,
"Number of functions marked as nounwind");
84 cl::desc(
"Try to propagate nonnull argument attributes from callsites to " 85 "caller functions."));
89 cl::desc(
"Stop inferring nounwind attribute during function-attrs pass"));
107 const SCCNodeSet &SCCNodes) {
125 bool ReadsMemory =
false;
126 bool WritesMemory =
false;
132 if (
auto *Call = dyn_cast<CallBase>(I)) {
137 if (!Call->hasOperandBundles() && Call->getCalledFunction() &&
138 SCCNodes.count(Call->getCalledFunction()))
182 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
184 if (!LI->isVolatile()) {
189 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(I)) {
191 if (!
SI->isVolatile()) {
196 }
else if (
VAArgInst *
VI = dyn_cast<VAArgInst>(I)) {
229 template <
typename AARGetterT>
230 static bool addReadAttrs(
const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
233 bool ReadsMemory =
false;
234 bool WritesMemory =
false;
260 bool MadeChange =
false;
262 assert(!(ReadsMemory && WritesMemory) &&
263 "Function marked read-only and write-only");
265 if (
F->doesNotAccessMemory())
269 if (
F->onlyReadsMemory() && ReadsMemory)
273 if (
F->doesNotReadMemory() && WritesMemory)
279 F->removeFnAttr(Attribute::ReadOnly);
280 F->removeFnAttr(Attribute::ReadNone);
281 F->removeFnAttr(Attribute::WriteOnly);
283 if (!WritesMemory && !ReadsMemory) {
285 F->removeFnAttr(Attribute::ArgMemOnly);
286 F->removeFnAttr(Attribute::InaccessibleMemOnly);
287 F->removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
291 if (WritesMemory && !ReadsMemory)
292 F->addFnAttr(Attribute::WriteOnly);
294 F->addFnAttr(ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);
296 if (WritesMemory && !ReadsMemory)
298 else if (ReadsMemory)
312 struct ArgumentGraphNode {
317 class ArgumentGraph {
320 using ArgumentMapTy = std::map<Argument *, ArgumentGraphNode>;
322 ArgumentMapTy ArgumentMap;
330 ArgumentGraphNode SyntheticRoot;
333 ArgumentGraph() { SyntheticRoot.Definition =
nullptr; }
337 iterator
begin() {
return SyntheticRoot.Uses.begin(); }
338 iterator
end() {
return SyntheticRoot.Uses.end(); }
339 ArgumentGraphNode *getEntryNode() {
return &SyntheticRoot; }
341 ArgumentGraphNode *operator[](
Argument *A) {
342 ArgumentGraphNode &Node = ArgumentMap[A];
344 SyntheticRoot.Uses.push_back(&Node);
353 ArgumentUsesTracker(
const SCCNodeSet &SCCNodes) : SCCNodes(SCCNodes) {}
355 void tooManyUses()
override { Captured =
true; }
357 bool captured(
const Use *U)
override {
359 if (!CS.getInstruction()) {
375 std::distance(const_cast<const Use *>(CS.arg_begin()), U);
377 assert(UseIndex < CS.data_operands_size() &&
378 "Indirect function calls should have been filtered above!");
380 if (UseIndex >= CS.getNumArgOperands()) {
382 assert(CS.hasOperandBundles() &&
"Must be!");
393 assert(F->
isVarArg() &&
"More params than args in non-varargs call");
398 Uses.push_back(&*std::next(F->
arg_begin(), UseIndex));
403 bool Captured =
false;
408 const SCCNodeSet &SCCNodes;
432 static ChildIteratorType
nodes_end(ArgumentGraph *AG) {
return AG->end(); }
456 while (!Worklist.
empty()) {
461 case Instruction::BitCast:
462 case Instruction::GetElementPtr:
463 case Instruction::PHI:
465 case Instruction::AddrSpaceCast:
468 if (Visited.
insert(&UU).second)
473 case Instruction::Invoke: {
474 bool Captures =
true;
479 auto AddUsersToWorklistIfCapturing = [&] {
482 if (Visited.
insert(&UU).second)
488 AddUsersToWorklistIfCapturing();
496 AddUsersToWorklistIfCapturing();
506 unsigned UseIndex = std::distance(CS.
arg_begin(), U);
513 "Data operand use expected!");
517 if (UseIndex >= F->
arg_size() && !IsOperandBundleUse) {
518 assert(F->
isVarArg() &&
"More params than args in non-varargs call");
528 if (IsOperandBundleUse ||
540 AddUsersToWorklistIfCapturing();
553 case Instruction::ICmp:
562 return IsRead ? Attribute::ReadOnly : Attribute::ReadNone;
567 bool Changed =
false;
574 if (!
F->hasExactDefinition())
577 if (
F->getReturnType()->isVoidTy())
585 auto FindRetArg = [&]() ->
Value * {
586 Value *RetArg =
nullptr;
588 if (
auto *
Ret = dyn_cast<ReturnInst>(BB.getTerminator())) {
591 Value *RetVal =
Ret->getReturnValue()->stripPointerCasts();
592 if (!isa<Argument>(RetVal) || RetVal->
getType() != F->getReturnType())
597 else if (RetArg != RetVal)
604 if (
Value *RetArg = FindRetArg()) {
605 auto *
A = cast<Argument>(RetArg);
606 A->addAttr(Attribute::Returned);
623 bool Changed =
false;
635 if (
auto *CalledFunc = CS.getCalledFunction()) {
636 for (
auto &CSArg : CalledFunc->args()) {
637 if (!CSArg.hasNonNullAttr())
644 if (FArg && !FArg->hasNonNullAttr()) {
645 FArg->addAttr(Attribute::NonNull);
660 bool Changed =
false;
670 if (!
F->hasExactDefinition())
677 if (
F->onlyReadsMemory() &&
F->doesNotThrow() &&
678 F->getReturnType()->isVoidTy()) {
681 if (
A->getType()->isPointerTy() && !
A->hasNoCaptureAttr()) {
682 A->addAttr(Attribute::NoCapture);
692 if (!
A->getType()->isPointerTy())
694 bool HasNonLocalUses =
false;
695 if (!
A->hasNoCaptureAttr()) {
696 ArgumentUsesTracker Tracker(SCCNodes);
698 if (!Tracker.Captured) {
699 if (Tracker.Uses.empty()) {
701 A->addAttr(Attribute::NoCapture);
708 ArgumentGraphNode *Node = AG[&*
A];
710 Node->Uses.push_back(AG[Use]);
712 HasNonLocalUses =
true;
718 if (!HasNonLocalUses && !
A->onlyReadsMemory()) {
729 R == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
743 const std::vector<ArgumentGraphNode *> &ArgumentSCC = *
I;
744 if (ArgumentSCC.size() == 1) {
745 if (!ArgumentSCC[0]->Definition)
749 if (ArgumentSCC[0]->Uses.size() == 1 &&
750 ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
751 Argument *
A = ArgumentSCC[0]->Definition;
752 A->
addAttr(Attribute::NoCapture);
759 bool SCCCaptured =
false;
760 for (
auto I = ArgumentSCC.begin(),
E = ArgumentSCC.end();
761 I !=
E && !SCCCaptured; ++
I) {
762 ArgumentGraphNode *Node = *
I;
763 if (Node->Uses.empty()) {
764 if (!Node->Definition->hasNoCaptureAttr())
774 for (ArgumentGraphNode *
I : ArgumentSCC) {
775 ArgumentSCCNodes.
insert(
I->Definition);
778 for (
auto I = ArgumentSCC.begin(),
E = ArgumentSCC.end();
779 I !=
E && !SCCCaptured; ++
I) {
780 ArgumentGraphNode *
N = *
I;
781 for (ArgumentGraphNode *
Use : N->Uses) {
792 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
793 Argument *
A = ArgumentSCC[i]->Definition;
794 A->
addAttr(Attribute::NoCapture);
811 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
812 Argument *
A = ArgumentSCC[i]->Definition;
814 if (K == Attribute::ReadNone)
816 if (K == Attribute::ReadOnly) {
817 ReadAttr = Attribute::ReadOnly;
825 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
826 Argument *
A = ArgumentSCC[i]->Definition;
831 ReadAttr == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
847 if (
ReturnInst *
Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
848 FlowsToReturn.
insert(
Ret->getReturnValue());
850 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
851 Value *RetVal = FlowsToReturn[i];
853 if (
Constant *
C = dyn_cast<Constant>(RetVal)) {
854 if (!
C->isNullValue() && !isa<UndefValue>(
C))
860 if (isa<Argument>(RetVal))
863 if (
Instruction *RVI = dyn_cast<Instruction>(RetVal))
864 switch (RVI->getOpcode()) {
866 case Instruction::BitCast:
867 case Instruction::GetElementPtr:
868 case Instruction::AddrSpaceCast:
869 FlowsToReturn.
insert(RVI->getOperand(0));
877 case Instruction::PHI: {
878 PHINode *PN = cast<PHINode>(RVI);
880 FlowsToReturn.
insert(IncValue);
885 case Instruction::Alloca:
888 case Instruction::Invoke: {
913 if (
F->returnDoesNotAlias())
919 if (!
F->hasExactDefinition())
924 if (!
F->getReturnType()->isPointerTy())
931 bool MadeChange =
false;
933 if (
F->returnDoesNotAlias() ||
934 !
F->getReturnType()->isPointerTy())
937 F->setReturnDoesNotAlias();
955 "nonnull only meaningful on pointer types");
960 if (
auto *
Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
961 FlowsToReturn.
insert(
Ret->getReturnValue());
963 auto &DL = F->getParent()->getDataLayout();
965 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
966 Value *RetVal = FlowsToReturn[i];
979 case Instruction::BitCast:
980 case Instruction::GetElementPtr:
981 case Instruction::AddrSpaceCast:
990 case Instruction::PHI: {
991 PHINode *PN = cast<PHINode>(RVI);
997 case Instruction::Invoke: {
1002 if (Callee && SCCNodes.count(Callee)) {
1021 bool SCCReturnsNonNull =
true;
1023 bool MadeChange =
false;
1030 Attribute::NonNull))
1036 if (!
F->hasExactDefinition())
1041 if (!
F->getReturnType()->isPointerTy())
1044 bool Speculative =
false;
1050 <<
" as nonnull\n");
1059 SCCReturnsNonNull =
false;
1062 if (SCCReturnsNonNull) {
1065 Attribute::NonNull) ||
1066 !
F->getReturnType()->isPointerTy())
1069 LLVM_DEBUG(
dbgs() <<
"SCC marking " <<
F->getName() <<
" as nonnull\n");
1087 class AttributeInferer {
1090 struct InferenceDescriptor {
1096 std::function<bool(const Function &)> SkipFunction;
1099 std::function<bool(Instruction &)> InstrBreaksAttribute;
1102 std::function<void(Function &)> SetAttribute;
1109 bool RequiresExactDefinition;
1116 : SkipFunction(SkipFunc), InstrBreaksAttribute(InstrScan),
1117 SetAttribute(SetAttr), AKind(AK),
1118 RequiresExactDefinition(ReqExactDef) {}
1125 void registerAttrInference(InferenceDescriptor AttrInference) {
1126 InferenceDescriptors.
push_back(AttrInference);
1129 bool run(
const SCCNodeSet &SCCNodes);
1134 bool AttributeInferer::run(
const SCCNodeSet &SCCNodes) {
1142 if (InferInSCC.
empty())
1147 if (ID.SkipFunction(*
F))
1152 return F->isDeclaration() ||
1153 (ID.RequiresExactDefinition && !
F->hasExactDefinition());
1160 InferInSCC, std::back_inserter(InferInThisFunc),
1161 [
F](
const InferenceDescriptor &ID) {
return !ID.SkipFunction(*
F); });
1163 if (InferInThisFunc.empty())
1168 llvm::erase_if(InferInThisFunc, [&](
const InferenceDescriptor &ID) {
1169 if (!ID.InstrBreaksAttribute(
I))
1174 return D.AKind == ID.AKind;
1180 if (InferInThisFunc.empty())
1185 if (InferInSCC.
empty())
1188 bool Changed =
false;
1194 for (
auto &
ID : InferInSCC) {
1195 if (
ID.SkipFunction(*
F))
1198 ID.SetAttribute(*
F);
1207 const SCCNodeSet &SCCNodes) {
1218 if (
const auto *CI = dyn_cast<CallInst>(&I)) {
1223 if (SCCNodes.count(
Callee) > 0)
1239 AttributeInferer AI;
1246 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1249 [](
const Function &
F) {
return !
F.isConvergent(); },
1255 LLVM_DEBUG(
dbgs() <<
"Removing convergent attr from fn " <<
F.getName()
1257 F.setNotConvergent();
1267 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1268 Attribute::NoUnwind,
1270 [](
const Function &
F) {
return F.doesNotThrow(); },
1277 <<
"Adding nounwind attr to fn " <<
F.getName() <<
"\n");
1278 F.setDoesNotThrow();
1284 return AI.run(SCCNodes);
1299 if (SCCNodes.size() != 1)
1310 for (
auto &
I : BB.instructionsWithoutDebug())
1324 template <
typename AARGetterT>
1326 bool HasUnknownCall) {
1327 bool Changed =
false;
1330 if (SCCNodes.empty())
1339 if (!HasUnknownCall) {
1365 SCCNodeSet SCCNodes;
1366 bool HasUnknownCall =
false;
1373 HasUnknownCall =
true;
1380 if (!HasUnknownCall)
1383 if (!CS.getCalledFunction()) {
1384 HasUnknownCall =
true;
1388 SCCNodes.insert(&F);
1422 "Deduce function attributes",
false,
false)
1429 return new PostOrderFunctionAttrsLegacyPass();
1432 template <
typename AARGetterT>
1439 SCCNodeSet SCCNodes;
1440 bool ExternalNode =
false;
1447 ExternalNode =
true;
1457 bool PostOrderFunctionAttrsLegacyPass::runOnSCC(
CallGraphSCC &SCC) {
1465 struct ReversePostOrderFunctionAttrsLegacyPass :
public ModulePass {
1469 ReversePostOrderFunctionAttrsLegacyPass() :
ModulePass(ID) {
1474 bool runOnModule(
Module &M)
override;
1488 "Deduce function attributes in RPO",
false,
false)
1494 return new ReversePostOrderFunctionAttrsLegacyPass();
1503 "This function has already been deduced as norecurs!");
1505 "Can only do top-down deduction for internal linkage functions!");
1515 for (
auto *U : F.
users()) {
1545 bool Changed =
false;
1552 bool ReversePostOrderFunctionAttrsLegacyPass::runOnModule(
Module &M) {
1556 auto &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
Pass interface - Implemented by all 'passes'.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
static cl::opt< bool > EnableNonnullArgPropagation("enable-nonnull-arg-prop", cl::Hidden, cl::desc("Try to propagate nonnull argument attributes from callsites to " "caller functions."))
static ChildIteratorType nodes_end(ArgumentGraph *AG)
Return a value (possibly void), from a function.
MemoryAccessKind
The three kinds of memory access relevant to 'readonly' and 'readnone' attributes.
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
const_iterator end(StringRef path)
Get end iterator over path.
iterator_range< use_iterator > uses()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
This callback is used in conjunction with PointerMayBeCaptured.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
size_type size() const
Determine the number of elements in the SetVector.
void removeAttr(Attribute::AttrKind Kind)
Remove attributes from an argument.
static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes)
Tests whether a function is "malloc-like".
A Module instance is used to store all the information related to an LLVM module. ...
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...
static constexpr LocationSize unknown()
static bool addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes)
Deduce returned attributes for the SCC.
void push_back(const T &Elt)
static bool setDoesNotRecurse(Function &F)
Implements a lazy call graph analysis and related passes for the new pass manager.
An immutable pass that tracks lazily created AssumptionCache objects.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
const Value * getTrueValue() const
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
The two locations do not alias at all.
bool hasRetAttr(Attribute::AttrKind Kind) const
Return true if this return value has the given attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
An instruction for reading from memory.
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
This defines the Use class.
MemoryAccessKind computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)
Returns the memory access properties of this copy of the function.
A proxy from a FunctionAnalysisManager to an SCC.
A node in the call graph for a module.
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph...
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
bool doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry &)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static bool addNonNullAttrs(const SCCNodeSet &SCCNodes)
Deduce nonnull attributes for the SCC.
static MemoryAccessKind 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...
inst_iterator inst_begin(Function *F)
This class represents the LLVM 'select' instruction.
static bool doesNotReadMemory(FunctionModRefBehavior MRB)
Checks if functions with the specified behavior are known to only write memory (or not access memory ...
ArgumentGraphNode * NodeRef
A Use represents the edge between a Value definition and its users.
static ChildIteratorType child_end(NodeRef N)
static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter)
This class is a functor to be used in legacy module or SCC passes for computing AA results for a func...
This file contains the simple types necessary to represent the attributes associated with functions a...
No attributes have been set.
bool doesNotAccessMemory() const
Determine if the call does not access memory.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
FunctionModRefBehavior getModRefBehavior(const CallBase *Call)
Return the behavior of the given call site.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Type * getType() const
All values are typed, get the type of this value.
bool insert(const value_type &X)
Insert a new element into the SetVector.
FunctionModRefBehavior
Summary of how a function affects memory in the program.
A lazily constructed view of the call graph of a module.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for storing to memory.
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
Value * getOperand(unsigned i) const
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter)
Deduce readonly/readnone attributes for the SCC.
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal=false)
Checks whether the given location points to constant memory, or if OrLocal is true whether it points ...
bool isVoidTy() const
Return true if this is 'void'.
const BasicBlock & getEntryBlock() const
void getAAMetadata(AAMDNodes &N, bool Merge=false) const
Fills the AAMDNodes structure with AA metadata from this instruction.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
Type * getReturnType() const
Returns the type of the ret val.
typename ArgumentGraphNode *::UnknownGraphTypeError NodeRef
void addAttr(Attribute::AttrKind Kind)
A set of analyses that are preserved following a run of a transformation pass.
unsigned const MachineRegisterInfo * MRI
The ModulePass which wraps up a CallGraph and the logic to build it.
unsigned getNumArgOperands() const
LLVM Basic Block Representation.
INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "functionattrs", "Deduce function attributes", false, false) INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isPointerTy() const
True if this is an instance of PointerType.
static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoUnwind inference predicate InstrBreaksAttribute.
A manager for alias analyses.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool mayThrow() const
Return true if this instruction may throw an exception.
Represent the analysis usage information of a pass.
static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
bool hasInternalLinkage() const
static bool addNoRecurseAttrsTopDown(Function &F)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
A node in the call graph.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Pass * createReversePostOrderFunctionAttrsPass()
createReversePostOrderFunctionAttrsPass - This pass walks SCCs of the call graph in RPO to deduce and...
bool onlyReadsMemory(const CallBase *Call)
Checks if the specified call is known to only read from non-volatile memory (or not access memory at ...
bool hasInAllocaAttr() const
Return true if this argument has the inalloca attribute.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
Pass * createPostOrderFunctionAttrsLegacyPass()
Create a legacy pass manager instance of a pass to compute function attrs in post-order.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
void getAAResultsAnalysisUsage(AnalysisUsage &AU)
A helper for the legacy pass manager to populate AU to add uses to make sure the analyses required by...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This function does not perform any non-local loads or stores to memory.
static cl::opt< bool > DisableNoUnwindInference("disable-nounwind-inference", cl::Hidden, cl::desc("Stop inferring nounwind attribute during function-attrs pass"))
bool doesNotRecurse() const
Determine if the function is known not to recurse, directly or indirectly.
Representation for a specific memory location.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
A SetVector that performs no allocations if smaller than a certain size.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
SmallVectorImpl< ArgumentGraphNode * >::iterator ChildIteratorType
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static NodeRef getEntryNode(ArgumentGraph *AG)
bool isConvergent() const
Determine if the call is convergent.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
LLVM_NODISCARD T pop_back_val()
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void setPreservesCFG()
This function should be called by the pass, iff they do not:
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static ChildIteratorType child_begin(NodeRef N)
amdgpu Simplify well known AMD library false FunctionCallee Callee
BBTy * getParent() const
Get the basic block containing the call site.
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to be non-zero when defined.
typename SuperClass::iterator iterator
iterator_range< user_iterator > users()
LLVM_NODISCARD bool isNoModRef(const ModRefInfo MRI)
static bool addNoAliasAttrs(const SCCNodeSet &SCCNodes)
Deduce noalias attributes for the SCC.
const Value * getFalseValue() const
static bool addArgumentAttrs(const SCCNodeSet &SCCNodes)
Deduce nocapture attributes for the SCC.
static bool inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes)
Infer attributes from all functions in the SCC by scanning every instruction for compliance to the at...
An analysis pass to compute the CallGraph for a Module.
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
static bool onlyAccessesArgPointees(FunctionModRefBehavior MRB)
Checks if functions with the specified behavior are known to read and write at most from objects poin...
The basic data container for the call graph of a Module of IR.
static bool addArgumentAttrsFromCallsites(Function &F)
If a callsite has arguments that are also arguments to the parent function, try to propagate attribut...
LLVM_NODISCARD bool empty() const
This file provides utility analysis objects describing memory locations.
void initializePostOrderFunctionAttrsLegacyPassPass(PassRegistry &)
bool hasExactDefinition() const
Return true if this global has an exact defintion.
const Function * getParent() const
Return the enclosing method, or null if none.
static NodeRef getEntryNode(NodeRef A)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
bool mayReadFromMemory() const
Return true if this instruction may read memory.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Deduce function attributes
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
Provides passes for computing function attributes based on interprocedural analyses.
static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes, bool &Speculative)
Tests whether this function is known to not return null.
static bool deriveAttrsInPostOrder(SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, bool HasUnknownCall)
This header provides classes for managing passes over SCCs of the call graph.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
An SCC of the call graph.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
rpo Deduce function attributes in RPO
static ChildIteratorType nodes_begin(ArgumentGraph *AG)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
LLVM_NODISCARD ModRefInfo createModRefInfo(const FunctionModRefBehavior FMRB)
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
print Print MemDeps of function
This is the interface for LLVM's primary stateless and local alias analysis.
inst_range instructions(Function *F)
inst_iterator inst_end(Function *F)
A container for analyses that lazily runs them and caches their results.
static bool isVolatile(Instruction *Inst)
This header defines various interfaces for pass management in LLVM.
bool hasNoCaptureAttr() const
Return true if this argument has the nocapture attribute.
static bool InstrBreaksNonConvergent(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for non-Convergent inference predicate InstrBreaksAttribute.
op_range incoming_values()
static Attribute::AttrKind determinePointerReadAttrs(Argument *A, const SmallPtrSet< Argument *, 8 > &SCCNodes)
Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
static bool deduceFunctionAttributeInRPO(Module &M, CallGraph &CG)
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results...
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=DefaultMaxUsesToExplore)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_NODISCARD bool isRefSet(const ModRefInfo MRI)
unsigned data_operands_size() const