66 #define DEBUG_TYPE "functionattrs" 68 STATISTIC(NumReadNone,
"Number of functions marked readnone");
69 STATISTIC(NumReadOnly,
"Number of functions marked readonly");
70 STATISTIC(NumWriteOnly,
"Number of functions marked writeonly");
71 STATISTIC(NumNoCapture,
"Number of arguments marked nocapture");
72 STATISTIC(NumReturned,
"Number of arguments marked returned");
73 STATISTIC(NumReadNoneArg,
"Number of arguments marked readnone");
74 STATISTIC(NumReadOnlyArg,
"Number of arguments marked readonly");
75 STATISTIC(NumNoAlias,
"Number of function returns marked noalias");
76 STATISTIC(NumNonNullReturn,
"Number of function returns marked nonnull");
77 STATISTIC(NumNoRecurse,
"Number of functions marked as norecurse");
78 STATISTIC(NumNoUnwind,
"Number of functions marked as nounwind");
85 cl::desc(
"Try to propagate nonnull argument attributes from callsites to " 86 "caller functions."));
90 cl::desc(
"Stop inferring nounwind attribute during function-attrs pass"));
108 const SCCNodeSet &SCCNodes) {
126 bool ReadsMemory =
false;
127 bool WritesMemory =
false;
133 if (
auto *Call = dyn_cast<CallBase>(I)) {
138 if (!Call->hasOperandBundles() && Call->getCalledFunction() &&
139 SCCNodes.count(Call->getCalledFunction()))
183 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
185 if (!LI->isVolatile()) {
190 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(I)) {
192 if (!
SI->isVolatile()) {
197 }
else if (
VAArgInst *
VI = dyn_cast<VAArgInst>(I)) {
230 template <
typename AARGetterT>
231 static bool addReadAttrs(
const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
234 bool ReadsMemory =
false;
235 bool WritesMemory =
false;
261 bool MadeChange =
false;
263 assert(!(ReadsMemory && WritesMemory) &&
264 "Function marked read-only and write-only");
266 if (
F->doesNotAccessMemory())
270 if (
F->onlyReadsMemory() && ReadsMemory)
274 if (
F->doesNotReadMemory() && WritesMemory)
284 if (!WritesMemory && !ReadsMemory) {
292 if (WritesMemory && !ReadsMemory)
297 if (WritesMemory && !ReadsMemory)
299 else if (ReadsMemory)
313 struct ArgumentGraphNode {
318 class ArgumentGraph {
321 using ArgumentMapTy = std::map<Argument *, ArgumentGraphNode>;
323 ArgumentMapTy ArgumentMap;
331 ArgumentGraphNode SyntheticRoot;
334 ArgumentGraph() { SyntheticRoot.Definition =
nullptr; }
338 iterator
begin() {
return SyntheticRoot.Uses.begin(); }
339 iterator
end() {
return SyntheticRoot.Uses.end(); }
340 ArgumentGraphNode *getEntryNode() {
return &SyntheticRoot; }
342 ArgumentGraphNode *operator[](
Argument *A) {
343 ArgumentGraphNode &Node = ArgumentMap[A];
345 SyntheticRoot.Uses.push_back(&Node);
354 ArgumentUsesTracker(
const SCCNodeSet &SCCNodes) : SCCNodes(SCCNodes) {}
356 void tooManyUses()
override { Captured =
true; }
358 bool captured(
const Use *U)
override {
360 if (!CS.getInstruction()) {
376 std::distance(const_cast<const Use *>(CS.arg_begin()), U);
378 assert(UseIndex < CS.data_operands_size() &&
379 "Indirect function calls should have been filtered above!");
381 if (UseIndex >= CS.getNumArgOperands()) {
383 assert(CS.hasOperandBundles() &&
"Must be!");
394 assert(F->
isVarArg() &&
"More params than args in non-varargs call");
399 Uses.push_back(&*std::next(F->
arg_begin(), UseIndex));
404 bool Captured =
false;
409 const SCCNodeSet &SCCNodes;
433 static ChildIteratorType
nodes_end(ArgumentGraph *AG) {
return AG->end(); }
457 while (!Worklist.
empty()) {
462 case Instruction::BitCast:
463 case Instruction::GetElementPtr:
464 case Instruction::PHI:
466 case Instruction::AddrSpaceCast:
469 if (Visited.
insert(&UU).second)
474 case Instruction::Invoke: {
475 bool Captures =
true;
480 auto AddUsersToWorklistIfCapturing = [&] {
483 if (Visited.
insert(&UU).second)
489 AddUsersToWorklistIfCapturing();
497 AddUsersToWorklistIfCapturing();
507 unsigned UseIndex = std::distance(CS.
arg_begin(), U);
514 "Data operand use expected!");
518 if (UseIndex >= F->
arg_size() && !IsOperandBundleUse) {
519 assert(F->
isVarArg() &&
"More params than args in non-varargs call");
529 if (IsOperandBundleUse ||
541 AddUsersToWorklistIfCapturing();
554 case Instruction::ICmp:
568 bool Changed =
false;
575 if (!
F->hasExactDefinition())
578 if (
F->getReturnType()->isVoidTy())
586 auto FindRetArg = [&]() ->
Value * {
587 Value *RetArg =
nullptr;
589 if (
auto *
Ret = dyn_cast<ReturnInst>(BB.getTerminator())) {
592 Value *RetVal =
Ret->getReturnValue()->stripPointerCasts();
593 if (!isa<Argument>(RetVal) || RetVal->
getType() != F->getReturnType())
598 else if (RetArg != RetVal)
605 if (
Value *RetArg = FindRetArg()) {
606 auto *
A = cast<Argument>(RetArg);
624 bool Changed =
false;
636 if (
auto *CalledFunc = CS.getCalledFunction()) {
637 for (
auto &CSArg : CalledFunc->args()) {
638 if (!CSArg.hasNonNullAttr())
645 if (FArg && !FArg->hasNonNullAttr()) {
661 bool Changed =
false;
671 if (!
F->hasExactDefinition())
678 if (
F->onlyReadsMemory() &&
F->doesNotThrow() &&
679 F->getReturnType()->isVoidTy()) {
682 if (
A->getType()->isPointerTy() && !
A->hasNoCaptureAttr()) {
693 if (!
A->getType()->isPointerTy())
695 bool HasNonLocalUses =
false;
696 if (!
A->hasNoCaptureAttr()) {
697 ArgumentUsesTracker Tracker(SCCNodes);
699 if (!Tracker.Captured) {
700 if (Tracker.Uses.empty()) {
709 ArgumentGraphNode *Node = AG[&*
A];
711 Node->Uses.push_back(AG[Use]);
713 HasNonLocalUses =
true;
719 if (!HasNonLocalUses && !
A->onlyReadsMemory()) {
744 const std::vector<ArgumentGraphNode *> &ArgumentSCC = *
I;
745 if (ArgumentSCC.size() == 1) {
746 if (!ArgumentSCC[0]->Definition)
750 if (ArgumentSCC[0]->Uses.size() == 1 &&
751 ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
752 Argument *
A = ArgumentSCC[0]->Definition;
760 bool SCCCaptured =
false;
761 for (
auto I = ArgumentSCC.begin(),
E = ArgumentSCC.end();
762 I !=
E && !SCCCaptured; ++
I) {
763 ArgumentGraphNode *Node = *
I;
764 if (Node->Uses.empty()) {
765 if (!Node->Definition->hasNoCaptureAttr())
775 for (ArgumentGraphNode *
I : ArgumentSCC) {
776 ArgumentSCCNodes.
insert(
I->Definition);
779 for (
auto I = ArgumentSCC.begin(),
E = ArgumentSCC.end();
780 I !=
E && !SCCCaptured; ++
I) {
781 ArgumentGraphNode *
N = *
I;
782 for (ArgumentGraphNode *
Use : N->Uses) {
793 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
794 Argument *
A = ArgumentSCC[i]->Definition;
812 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
813 Argument *
A = ArgumentSCC[i]->Definition;
826 for (
unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
827 Argument *
A = ArgumentSCC[i]->Definition;
848 if (
ReturnInst *
Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
849 FlowsToReturn.
insert(
Ret->getReturnValue());
851 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
852 Value *RetVal = FlowsToReturn[i];
854 if (
Constant *
C = dyn_cast<Constant>(RetVal)) {
855 if (!
C->isNullValue() && !isa<UndefValue>(
C))
861 if (isa<Argument>(RetVal))
864 if (
Instruction *RVI = dyn_cast<Instruction>(RetVal))
865 switch (RVI->getOpcode()) {
867 case Instruction::BitCast:
868 case Instruction::GetElementPtr:
869 case Instruction::AddrSpaceCast:
870 FlowsToReturn.
insert(RVI->getOperand(0));
878 case Instruction::PHI: {
879 PHINode *PN = cast<PHINode>(RVI);
881 FlowsToReturn.
insert(IncValue);
886 case Instruction::Alloca:
889 case Instruction::Invoke: {
914 if (
F->returnDoesNotAlias())
920 if (!
F->hasExactDefinition())
925 if (!
F->getReturnType()->isPointerTy())
932 bool MadeChange =
false;
934 if (
F->returnDoesNotAlias() ||
935 !
F->getReturnType()->isPointerTy())
938 F->setReturnDoesNotAlias();
956 "nonnull only meaningful on pointer types");
961 if (
auto *
Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
962 FlowsToReturn.
insert(
Ret->getReturnValue());
964 auto &DL = F->getParent()->getDataLayout();
966 for (
unsigned i = 0; i != FlowsToReturn.
size(); ++i) {
967 Value *RetVal = FlowsToReturn[i];
980 case Instruction::BitCast:
981 case Instruction::GetElementPtr:
982 case Instruction::AddrSpaceCast:
991 case Instruction::PHI: {
992 PHINode *PN = cast<PHINode>(RVI);
998 case Instruction::Invoke: {
1003 if (Callee && SCCNodes.count(Callee)) {
1022 bool SCCReturnsNonNull =
true;
1024 bool MadeChange =
false;
1037 if (!
F->hasExactDefinition())
1042 if (!
F->getReturnType()->isPointerTy())
1045 bool Speculative =
false;
1051 <<
" as nonnull\n");
1060 SCCReturnsNonNull =
false;
1063 if (SCCReturnsNonNull) {
1067 !
F->getReturnType()->isPointerTy())
1070 LLVM_DEBUG(
dbgs() <<
"SCC marking " <<
F->getName() <<
" as nonnull\n");
1088 class AttributeInferer {
1091 struct InferenceDescriptor {
1097 std::function<bool(const Function &)> SkipFunction;
1100 std::function<bool(Instruction &)> InstrBreaksAttribute;
1103 std::function<void(Function &)> SetAttribute;
1110 bool RequiresExactDefinition;
1117 : SkipFunction(SkipFunc), InstrBreaksAttribute(InstrScan),
1118 SetAttribute(SetAttr), AKind(AK),
1119 RequiresExactDefinition(ReqExactDef) {}
1126 void registerAttrInference(InferenceDescriptor AttrInference) {
1127 InferenceDescriptors.
push_back(AttrInference);
1130 bool run(
const SCCNodeSet &SCCNodes);
1135 bool AttributeInferer::run(
const SCCNodeSet &SCCNodes) {
1143 if (InferInSCC.
empty())
1148 if (ID.SkipFunction(*
F))
1153 return F->isDeclaration() ||
1154 (ID.RequiresExactDefinition && !
F->hasExactDefinition());
1161 InferInSCC, std::back_inserter(InferInThisFunc),
1162 [
F](
const InferenceDescriptor &ID) {
return !ID.SkipFunction(*
F); });
1164 if (InferInThisFunc.empty())
1169 llvm::erase_if(InferInThisFunc, [&](
const InferenceDescriptor &ID) {
1170 if (!ID.InstrBreaksAttribute(
I))
1175 return D.AKind == ID.AKind;
1181 if (InferInThisFunc.empty())
1186 if (InferInSCC.
empty())
1189 bool Changed =
false;
1195 for (
auto &
ID : InferInSCC) {
1196 if (
ID.SkipFunction(*
F))
1199 ID.SetAttribute(*
F);
1208 const SCCNodeSet &SCCNodes) {
1219 if (
const auto *CI = dyn_cast<CallInst>(&I)) {
1224 if (SCCNodes.count(
Callee) > 0)
1240 AttributeInferer AI;
1247 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1250 [](
const Function &
F) {
return !
F.isConvergent(); },
1256 LLVM_DEBUG(
dbgs() <<
"Removing convergent attr from fn " <<
F.getName()
1258 F.setNotConvergent();
1268 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1271 [](
const Function &
F) {
return F.doesNotThrow(); },
1278 <<
"Adding nounwind attr to fn " <<
F.getName() <<
"\n");
1279 F.setDoesNotThrow();
1285 return AI.run(SCCNodes);
1300 if (SCCNodes.size() != 1)
1311 for (
auto &
I : BB.instructionsWithoutDebug())
1325 template <
typename AARGetterT>
1327 bool HasUnknownCall) {
1328 bool Changed =
false;
1331 if (SCCNodes.empty())
1340 if (!HasUnknownCall) {
1366 SCCNodeSet SCCNodes;
1367 bool HasUnknownCall =
false;
1374 HasUnknownCall =
true;
1381 if (!HasUnknownCall)
1384 if (!CS.getCalledFunction()) {
1385 HasUnknownCall =
true;
1389 SCCNodes.insert(&F);
1423 "Deduce function attributes",
false,
false)
1430 return new PostOrderFunctionAttrsLegacyPass();
1433 template <
typename AARGetterT>
1440 SCCNodeSet SCCNodes;
1441 bool ExternalNode =
false;
1448 ExternalNode =
true;
1458 bool PostOrderFunctionAttrsLegacyPass::runOnSCC(
CallGraphSCC &SCC) {
1466 struct ReversePostOrderFunctionAttrsLegacyPass :
public ModulePass {
1470 ReversePostOrderFunctionAttrsLegacyPass() :
ModulePass(ID) {
1475 bool runOnModule(
Module &M)
override;
1489 "Deduce function attributes in RPO",
false,
false)
1495 return new ReversePostOrderFunctionAttrsLegacyPass();
1504 "This function has already been deduced as norecurs!");
1506 "Can only do top-down deduction for internal linkage functions!");
1516 for (
auto *U : F.
users()) {
1546 bool Changed =
false;
1553 bool ReversePostOrderFunctionAttrsLegacyPass::runOnModule(
Module &M) {
1557 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.
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
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.
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.
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...
void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry &)
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
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...
unsigned data_operands_size() const
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.
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.
amdgpu Simplify well known AMD library false Value * Callee
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.
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)
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 doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
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.
unsigned getNumArgOperands() const
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)
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:
unsigned getNumIncomingValues() const
Return the number of incoming edges.
BBTy * getParent() const
Get the basic block containing the call site.
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)
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...
bool doesNotAccessMemory() const
Determine if the call does not access memory.
amdgpu Simplify well known AMD library false Value Value * Arg
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...
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasRetAttr(Attribute::AttrKind Kind) const
Return true if this return value has the given attribute.
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)
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.
bool isConvergent() const
Determine if the call is convergent.
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)