LLVM: lib/Transforms/IPO/FunctionAttrs.cpp File Reference (original) (raw)

This file implements interprocedural passes which walk the call-graph deducing and/or propagating function attributes. More...

Go to the source code of this file.

Namespaces
namespace llvm
This is an optimization pass for GlobalISel generic memory operations.
Macros
#define DEBUG_TYPE "function-attrs"
Functions
STATISTIC (NumMemoryAttr, "Number of functions with improved memory attribute")
STATISTIC (NumCapturesNone, "Number of arguments marked captures(none)")
STATISTIC (NumCapturesPartial, "Number of arguments marked with captures " "attribute other than captures(none)")
STATISTIC (NumReturned, "Number of arguments marked returned")
STATISTIC (NumReadNoneArg, "Number of arguments marked readnone")
STATISTIC (NumReadOnlyArg, "Number of arguments marked readonly")
STATISTIC (NumWriteOnlyArg, "Number of arguments marked writeonly")
STATISTIC (NumNoAlias, "Number of function returns marked noalias")
STATISTIC (NumNonNullReturn, "Number of function returns marked nonnull")
STATISTIC (NumNoUndefReturn, "Number of function returns marked noundef")
STATISTIC (NumNoRecurse, "Number of functions marked as norecurse")
STATISTIC (NumNoUnwind, "Number of functions marked as nounwind")
STATISTIC (NumNoFree, "Number of functions marked as nofree")
STATISTIC (NumWillReturn, "Number of functions marked as willreturn")
STATISTIC (NumNoSync, "Number of functions marked as nosync")
STATISTIC (NumCold, "Number of functions marked as cold")
STATISTIC (NumThinLinkNoRecurse, "Number of functions marked as norecurse during thinlink")
STATISTIC (NumThinLinkNoUnwind, "Number of functions marked as nounwind during thinlink")
static void addCapturesStat (CaptureInfo CI)
static void addLocAccess (MemoryEffects &ME, const MemoryLocation &Loc, ModRefInfo MR, AAResults &AAR)
static void addArgLocs (MemoryEffects &ME, const CallBase *Call, ModRefInfo ArgMR, AAResults &AAR)
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 current SCC.
template
static void addMemoryAttrs (const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, SmallPtrSet< Function *, 8 > &Changed)
Deduce readonly/readnone/writeonly attributes for the SCC.
static FunctionSummary * calculatePrevailingSummary (ValueInfo VI, DenseMap< ValueInfo, FunctionSummary * > &CachedPrevailingSummary, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing)
static Attribute::AttrKind determinePointerAccessAttrs (Argument *A, const SmallPtrSet< Argument *, 8 > &SCCNodes)
Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
static void addArgumentReturnedAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce returned attributes for the SCC.
static bool addArgumentAttrsFromCallsites (Function &F)
If a callsite has arguments that are also arguments to the parent function, try to propagate attributes from the callsite's arguments to the parent's arguments.
static bool addAccessAttr (Argument *A, Attribute::AttrKind R)
static bool inferInitializes (Argument &A, Function &F)
static void addArgumentAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed, bool SkipInitializes)
Deduce nocapture attributes for the SCC.
static bool isFunctionMallocLike (Function *F, const SCCNodeSet &SCCNodes)
Tests whether a function is "malloc-like".
static void addNoAliasAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noalias attributes for the SCC.
static bool isReturnNonNull (Function *F, const SCCNodeSet &SCCNodes, bool &Speculative)
Tests whether this function is known to not return null.
static void addNonNullAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce nonnull attributes for the SCC.
static void addNoUndefAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noundef attributes for the SCC.
static bool InstrBreaksNonConvergent (Instruction &I, const SCCNodeSet &SCCNodes)
Helper for non-Convergent inference predicate InstrBreaksAttribute.
static bool InstrBreaksNonThrowing (Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoUnwind inference predicate InstrBreaksAttribute.
static bool InstrBreaksNoFree (Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoFree inference predicate InstrBreaksAttribute.
static bool isOrderedAtomic (Instruction *I)
static bool InstrBreaksNoSync (Instruction &I, const SCCNodeSet &SCCNodes)
static void inferConvergent (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Attempt to remove convergent function attribute when possible.
static void inferAttrsFromFunctionBodies (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Infer attributes from all functions in the SCC by scanning every instruction for compliance to the attribute assumptions.
static bool mayHaveRecursiveCallee (Function &F, bool AnyFunctionsAddressIsTaken=true)
static void addNoRecurseAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static void addNoReturnAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool allPathsGoThroughCold (Function &F)
static void addColdAttrs (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool functionWillReturn (const Function &F)
static void addWillReturn (const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static SCCNodesResult createSCCNodeSet (ArrayRef< Function * > Functions)
template
static SmallPtrSet< Function *, 8 > deriveAttrsInPostOrder (ArrayRef< Function * > Functions, AARGetterT &&AARGetter, bool ArgAttrsOnly)
template
static bool runImpl (CallGraphSCC &SCC, AARGetterT AARGetter)
static bool addNoRecurseAttrsTopDown (Function &F)
static bool deduceFunctionAttributeInRPO (Module &M, LazyCallGraph &CG)
Variables
static cl::opt< bool > EnableNonnullArgPropagation ("enable-nonnull-arg-prop", cl::init(true), cl::Hidden, cl::desc("Try to propagate nonnull argument attributes from callsites to " "caller functions."))
static cl::opt< bool > DisableNoUnwindInference ("disable-nounwind-inference", cl::Hidden, cl::desc("Stop inferring nounwind attribute during function-attrs pass"))
static cl::opt< bool > DisableNoFreeInference ("disable-nofree-inference", cl::Hidden, cl::desc("Stop inferring nofree attribute during function-attrs pass"))
static cl::opt< bool > DisableThinLTOPropagation ("disable-thinlto-funcattrs", cl::init(true), cl::Hidden, cl::desc("Don't propagate function-attrs in thinLTO"))

This file implements interprocedural passes which walk the call-graph deducing and/or propagating function attributes.

Definition in file FunctionAttrs.cpp.

DEBUG_TYPE

#define DEBUG_TYPE "function-attrs"

addAccessAttr()

addArgLocs()

addArgumentAttrs()

Deduce nocapture attributes for the SCC.

Definition at line 1239 of file FunctionAttrs.cpp.

References A(), addAccessAttr(), addArgumentAttrsFromCallsites(), addCapturesStat(), B(), llvm::capturesAll(), llvm::capturesAnyProvenance(), llvm::capturesNothing(), Changed, llvm::SmallPtrSetImpl< PtrType >::count(), determinePointerAccessAttrs(), F, llvm::Attribute::getWithCaptureInfo(), I, inferInitializes(), llvm::SmallPtrSetImpl< PtrType >::insert(), N, llvm::Attribute::None, llvm::None, llvm::CaptureInfo::none(), llvm::PointerMayBeCaptured(), llvm::scc_begin(), and Uses.

Referenced by deriveAttrsInPostOrder().

addArgumentAttrsFromCallsites()

addArgumentReturnedAttrs()

addCapturesStat()

addColdAttrs()

addLocAccess()

addMemoryAttrs()

template

void addMemoryAttrs ( const SCCNodeSet & SCCNodes, AARGetterT && AARGetter, SmallPtrSet< Function *, 8 > & Changed ) static

addNoAliasAttrs()

addNonNullAttrs()

addNoRecurseAttrs()

addNoRecurseAttrsTopDown()

addNoReturnAttrs()

addNoUndefAttrs()

Deduce noundef attributes for the SCC.

Definition at line 1681 of file FunctionAttrs.cpp.

References llvm::all_of(), Changed, llvm::computeConstantRange(), llvm::ConstantRange::contains(), DL, llvm::dyn_cast(), F, llvm::Value::getPointerAlignment(), llvm::Attribute::getRange(), llvm::BasicBlock::getTerminator(), llvm::isGuaranteedNotToBeUndefOrPoison(), llvm::isKnownNonZero(), and llvm::Attribute::isValid().

Referenced by deriveAttrsInPostOrder().

addWillReturn()

allPathsGoThroughCold()

Definition at line 2136 of file FunctionAttrs.cpp.

References llvm::any_of(), llvm::dyn_cast(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), F, llvm::CallBase::hasFnAttr(), I, llvm::SmallVectorImpl< T >::pop_back_val(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::successors(), and llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::try_emplace().

Referenced by addColdAttrs().

calculatePrevailingSummary()

At this point, prevailing symbols have been resolved. The following leads to returning a conservative result:

These next 2 cases should not happen and will assert:

Otherwise, we calculate attributes for a function as:

  1. If we have a local linkage, take its attributes. If there's somehow multiple, bail and go conservative.
  2. If we have an external/WeakODR/LinkOnceODR linkage check that it is prevailing, take its attributes.
  3. If we have a Weak/LinkOnce linkage the copies can have semantic differences. However, if the prevailing copy is known it will be used so take its attributes. If the prevailing copy is in a native file all IR copies will be dead and propagation will go conservative.
  4. AvailableExternally summaries without a prevailing copy are known to occur in a couple of circumstances: a. An internal function gets imported due to its caller getting imported, it becomes AvailableExternally but no prevailing definition exists. Because it has to get imported along with its caller the attributes will be captured by propagating on its caller. b. C++11 [temp.explicit]p10 can generate AvailableExternally definitions of explicitly instanced template declarations for inlining which are ultimately dropped from the TU. Since this is localized to the TU the attributes will have already made it to the callers. These are edge cases and already captured by their callers so we ignore these for now. If they become relevant to optimize in the future this can be revisited.
  5. Otherwise, go conservative.

Definition at line 315 of file FunctionAttrs.cpp.

References assert(), llvm::dbgs(), llvm::dyn_cast(), llvm::GlobalValue::isAvailableExternallyLinkage(), llvm::GlobalValue::isExternalLinkage(), llvm::GlobalValue::isLinkOnceAnyLinkage(), llvm::GlobalValue::isLinkOnceODRLinkage(), llvm::GlobalValue::isLocalLinkage(), llvm::GlobalValue::isWeakAnyLinkage(), llvm::GlobalValue::isWeakODRLinkage(), Linkage, LLVM_DEBUG, Local, and llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::try_emplace().

Referenced by llvm::thinLTOPropagateFunctionAttrs().

checkFunctionMemoryAccess()

Returns the memory access attribute for function F using AAR for AA results, where SCCNodes is the current SCC.

If ThisBody is true, this function may examine the function body and will return a result pertaining to this copy of the function. If it is false, the result will be based only on AA results for the function declaration; it will be assumed that some other (perhaps less optimized) version of the function may be selected at link time.

The return value is split into two parts: Memory effects that always apply, and additional memory effects that apply if any of the functions in the SCC can access argmem.

Definition at line 172 of file FunctionAttrs.cpp.

References addArgLocs(), addLocAccess(), llvm::ArgMem, llvm::MemoryEffectsBase< IRMemLocation >::argMemOnly(), Call, llvm::MemoryEffectsBase< LocationEnum >::doesNotAccessMemory(), llvm::dyn_cast(), F, llvm::AAResults::getMemoryEffects(), llvm::MemoryEffectsBase< LocationEnum >::getModRef(), llvm::MemoryLocation::getOrNone(), llvm::MemoryEffectsBase< LocationEnum >::getWithoutLoc(), I, llvm::MemoryEffectsBase< IRMemLocation >::inaccessibleMemOnly(), instructions, llvm::isa(), llvm::Mod, llvm::ModRef, llvm::NoModRef, llvm::MemoryEffectsBase< IRMemLocation >::none(), llvm::Other, and llvm::Ref.

Referenced by addMemoryAttrs(), and llvm::computeFunctionBodyMemoryAccess().

createSCCNodeSet()

deduceFunctionAttributeInRPO()

deriveAttrsInPostOrder()

template

Definition at line 2258 of file FunctionAttrs.cpp.

References addArgumentAttrs(), addArgumentReturnedAttrs(), addColdAttrs(), addMemoryAttrs(), addNoAliasAttrs(), addNonNullAttrs(), addNoRecurseAttrs(), addNoReturnAttrs(), addNoUndefAttrs(), addWillReturn(), Changed, createSCCNodeSet(), F, llvm::inferAttributesFromOthers(), inferAttrsFromFunctionBodies(), and inferConvergent().

Referenced by llvm::PostOrderFunctionAttrsPass::run(), and runImpl().

determinePointerAccessAttrs()

Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.

Definition at line 861 of file FunctionAttrs.cpp.

References A(), llvm::ArgMem, llvm::capturesAnyProvenance(), llvm::cast(), llvm::SmallPtrSetImpl< PtrType >::count(), llvm::CallBase::dataOperandHasImpliedAttr(), llvm::CallBase::doesNotAccessMemory(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), F, llvm::CallBase::getCalledFunction(), llvm::CallBase::getCaptureInfo(), llvm::CallBase::getDataOperandNo(), llvm::CallBase::getMemoryEffects(), llvm::MemoryEffectsBase< LocationEnum >::getModRef(), I, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::CallBase::isArgOperand(), llvm::CallBase::isCallee(), llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(), llvm::isModSet(), llvm::isNoModRef(), llvm::isRefSet(), llvm::Attribute::None, llvm::CallBase::onlyReadsMemory(), llvm::SmallVectorImpl< T >::pop_back_val(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), and llvm::Value::uses().

Referenced by addArgumentAttrs().

functionWillReturn()

inferAttrsFromFunctionBodies()

inferConvergent()

inferInitializes()

Definition at line 1119 of file FunctionAttrs.cpp.

References _, A(), llvm::append_range(), assert(), llvm::ConstantRangeList::empty(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::end(), F, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::find(), llvm::Attribute::get(), Info, llvm::ConstantRangeList::intersectWith(), LHS, llvm::post_order(), llvm::ConstantRangeList::rangesRef(), llvm::reverse(), RHS, llvm::sort(), llvm::ConstantRangeList::subtract(), llvm::successors(), and llvm::ConstantRangeList::unionWith().

Referenced by addArgumentAttrs().

InstrBreaksNoFree()

InstrBreaksNonConvergent()

InstrBreaksNonThrowing()

InstrBreaksNoSync()

isFunctionMallocLike()

Tests whether a function is "malloc-like".

A function is "malloc-like" if it returns either null or a pointer that doesn't alias any other pointer visible to the caller.

Definition at line 1448 of file FunctionAttrs.cpp.

References llvm::CallingConv::C, llvm::cast(), llvm::dyn_cast(), F, llvm::CallBase::getCalledFunction(), llvm::CallBase::hasRetAttr(), llvm::PHINode::incoming_values(), llvm::SetVector< T, Vector, Set, N >::insert(), llvm::SetVector< T, Vector, Set, N >::insert_range(), llvm::isa(), llvm::PointerMayBeCaptured(), and llvm::SetVector< T, Vector, Set, N >::size().

Referenced by addNoAliasAttrs().

isOrderedAtomic()

isReturnNonNull()

Tests whether this function is known to not return null.

Requires that the function returns a pointer.

Returns true if it believes the function will not return a null, and sets Speculative based on whether the returned conclusion is a speculative conclusion due to SCC calls.

Definition at line 1553 of file FunctionAttrs.cpp.

References assert(), llvm::cast(), DL, llvm::dyn_cast(), F, llvm::CallBase::getCalledFunction(), llvm::PHINode::getIncomingValue(), llvm::PHINode::getNumIncomingValues(), llvm::Instruction::getOpcode(), llvm::User::getOperand(), llvm::SetVector< T, Vector, Set, N >::insert(), llvm::isKnownNonZero(), llvm_unreachable, and llvm::SetVector< T, Vector, Set, N >::size().

Referenced by addNonNullAttrs().

mayHaveRecursiveCallee()

bool mayHaveRecursiveCallee ( Function & F, bool AnyFunctionsAddressIsTaken = true ) static

runImpl()

template

STATISTIC() [1/18]

STATISTIC ( NumCapturesNone ,
"Number of arguments marked captures(none)" )

STATISTIC() [2/18]

STATISTIC ( NumCapturesPartial ,
"Number of arguments marked with captures " "attribute other than captures(none)" )

STATISTIC() [3/18]

STATISTIC ( NumCold ,
"Number of functions marked as cold" )

STATISTIC() [4/18]

STATISTIC ( NumMemoryAttr ,
"Number of functions with improved memory attribute" )

STATISTIC() [5/18]

STATISTIC ( NumNoAlias ,
"Number of function returns marked noalias" )

STATISTIC() [6/18]

STATISTIC ( NumNoFree ,
"Number of functions marked as nofree" )

STATISTIC() [7/18]

STATISTIC ( NumNonNullReturn ,
"Number of function returns marked nonnull" )

STATISTIC() [8/18]

STATISTIC ( NumNoRecurse ,
"Number of functions marked as norecurse" )

STATISTIC() [9/18]

STATISTIC ( NumNoSync ,
"Number of functions marked as nosync" )

STATISTIC() [10/18]

STATISTIC ( NumNoUndefReturn ,
"Number of function returns marked noundef" )

STATISTIC() [11/18]

STATISTIC ( NumNoUnwind ,
"Number of functions marked as nounwind" )

STATISTIC() [12/18]

STATISTIC ( NumReadNoneArg ,
"Number of arguments marked readnone" )

STATISTIC() [13/18]

STATISTIC ( NumReadOnlyArg ,
"Number of arguments marked readonly" )

STATISTIC() [14/18]

STATISTIC ( NumReturned ,
"Number of arguments marked returned" )

STATISTIC() [15/18]

STATISTIC ( NumThinLinkNoRecurse ,
"Number of functions marked as norecurse during thinlink" )

STATISTIC() [16/18]

STATISTIC ( NumThinLinkNoUnwind ,
"Number of functions marked as nounwind during thinlink" )

STATISTIC() [17/18]

STATISTIC ( NumWillReturn ,
"Number of functions marked as willreturn" )

STATISTIC() [18/18]

STATISTIC ( NumWriteOnlyArg ,
"Number of arguments marked writeonly" )

DisableNoFreeInference

cl::opt< bool > DisableNoFreeInference("disable-nofree-inference", cl::Hidden, cl::desc("Stop inferring nofree attribute during function-attrs pass")) ( "disable-nofree-inference" , cl::Hidden , cl::desc("Stop inferring nofree attribute during function-attrs pass") ) static

DisableNoUnwindInference

cl::opt< bool > DisableNoUnwindInference("disable-nounwind-inference", cl::Hidden, cl::desc("Stop inferring nounwind attribute during function-attrs pass")) ( "disable-nounwind-inference" , cl::Hidden , cl::desc("Stop inferring nounwind attribute during function-attrs pass") ) static

DisableThinLTOPropagation

cl::opt< bool > DisableThinLTOPropagation("disable-thinlto-funcattrs", cl::init(true), cl::Hidden, cl::desc("Don't propagate function-attrs in thinLTO")) ( "disable-thinlto-funcattrs" , cl::init(true) , cl::Hidden , cl::desc("Don't propagate function-attrs in thinLTO") ) static

EnableNonnullArgPropagation

cl::opt< bool > EnableNonnullArgPropagation("enable-nonnull-arg-prop", cl::init(true), cl::Hidden, cl::desc("Try to propagate nonnull argument attributes from callsites to " "caller functions.")) ( "enable-nonnull-arg-prop" , cl::init(true) , cl::Hidden , cl::desc("Try to propagate nonnull argument attributes from callsites to " "caller functions.") ) static