32#define DEBUG_TYPE "capture-tracking"
34STATISTIC(NumCaptured,
"Number of pointers maybe captured");
35STATISTIC(NumNotCaptured,
"Number of pointers not captured");
36STATISTIC(NumCapturedBefore,
"Number of pointers maybe captured before");
37STATISTIC(NumNotCapturedBefore,
"Number of pointers not captured before");
47 cl::desc(
"Maximal number of uses to explore."),
62 : Mask(Mask), StopFn(StopFn) {}
64 void tooManyUses()
override {
70 Action captured(
const Use *U, UseCaptureInfo CI)
override {
94 CapturesBefore(
bool ReturnCaptures,
const Instruction *
I,
95 const DominatorTree *DT,
bool IncludeI,
const LoopInfo *LI,
98 : BeforeHere(
I), DT(DT), ReturnCaptures(ReturnCaptures),
99 IncludeI(IncludeI), LI(LI),
Mask(
Mask), StopFn(StopFn) {}
101 void tooManyUses()
override { CC =
Mask; }
103 bool isSafeToPrune(Instruction *
I) {
116 Action captured(
const Use *U, UseCaptureInfo CI)
override {
119 return ContinueIgnoringReturn;
124 if (isSafeToPrune(
I))
126 return ContinueIgnoringReturn;
132 return StopFn(CC) ? Stop :
Continue;
136 const DominatorTree *DT;
161 void tooManyUses()
override {
164 EarliestCapture = &*
F.getEntryBlock().begin();
167 Action captured(
const Use *U, UseCaptureInfo CI)
override {
172 if (!EarliestCapture)
184 const DominatorTree &DT;
197 unsigned MaxUsesToExplore) {
199 "It doesn't make sense to ask whether a global is captured.");
203 SimpleCaptureTracker SCT(Mask, StopFn);
211 return {SCT.CC, SCT.CCWithRet};
215 unsigned MaxUsesToExplore) {
225 unsigned MaxUsesToExplore) {
227 "It doesn't make sense to ask whether a global is captured.");
234 CapturesBefore CB(ReturnCaptures,
I, DT, IncludeI, LI, Mask, StopFn);
239 ++NumNotCapturedBefore;
246 unsigned MaxUsesToExplore,
253std::pair<Instruction *, CaptureResult>
257 "It doesn't make sense to ask whether a global is captured.");
259 EarliestCaptures CB(
F, DT, Mask);
264 ++NumNotCapturedBefore;
265 return {CB.EarliestCapture, {CB.CC, CB.CCWithRet}};
275 switch (
I->getOpcode()) {
276 case Instruction::Call:
277 case Instruction::Invoke: {
290 if (
MI->isVolatile())
299 if (
Call->isCallee(&U))
302 assert(
Call->isDataOperand(&U) &&
"Non-callee must be data operand");
308 if (
Call->onlyReadsMemory() &&
Call->getType()->isVoidTy())
314 case Instruction::Load:
319 case Instruction::VAArg:
322 case Instruction::Store:
324 if (U.getOperandNo() == 0)
326 I->getMetadata(LLVMContext::MD_captures));
332 case Instruction::AtomicRMW: {
339 if (U.getOperandNo() == 1 || ARMWI->isVolatile())
343 case Instruction::AtomicCmpXchg: {
350 if (U.getOperandNo() == 1 || U.getOperandNo() == 2 || ACXI->isVolatile())
354 case Instruction::GetElementPtr:
357 if (
I->getType()->isVectorTy())
360 case Instruction::BitCast:
361 case Instruction::PHI:
362 case Instruction::Select:
363 case Instruction::AddrSpaceCast:
366 case Instruction::PtrToAddr:
372 case Instruction::ICmp: {
373 unsigned Idx = U.getOperandNo();
374 unsigned OtherIdx = 1 - Idx;
383 if (U->getType()->getPointerAddressSpace() == 0)
405 unsigned MaxUsesToExplore) {
406 assert(V->getType()->isPointerTy() &&
"Capture is for pointers only!");
407 if (MaxUsesToExplore == 0)
414 auto AddUses = [&](
const Value *V) {
415 for (
const Use &U : V->
uses()) {
418 if (Visited.
size() >= MaxUsesToExplore) {
422 if (!Visited.
insert(&U).second)
433 while (!Worklist.
empty()) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< unsigned > DefaultMaxUsesToExplore("capture-tracking-max-uses-to-explore", cl::Hidden, cl::desc("Maximal number of uses to explore."), cl::init(100))
The default value for MaxUsesToExplore argument.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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)
Represents which components of the pointer may be captured in which location.
CaptureComponents getOtherComponents() const
Get components potentially captured through locations other than the return value.
CaptureComponents getRetComponents() const
Get components potentially captured by the return value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
static LLVM_ABI CaptureComponents toCaptureComponents(const MDNode *MD)
Convert !captures metadata to CaptureComponents. MD may be nullptr.
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.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
iterator_range< use_iterator > uses()
An efficient, type-erasing, non-owning reference to a callable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
LLVM_ABI unsigned getDefaultMaxUsesToExploreForCaptureTracking()
getDefaultMaxUsesToExploreForCaptureTracking - Return default value of the maximal number of uses to ...
LLVM_ABI bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, const Instruction *I, const DominatorTree *DT, bool IncludeI=false, unsigned MaxUsesToExplore=0, const LoopInfo *LI=nullptr)
PointerMayBeCapturedBefore - Return true if this pointer value may be captured by the enclosing funct...
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
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.
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 isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
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 std::pair< Instruction *, CaptureResult > FindEarliestCapture(const Value *V, Function &F, const DominatorTree &DT, CaptureComponents Mask, unsigned MaxUsesToExplore=0)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool capturesAnything(CaptureComponents CC)
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
bool capturesNothing(CaptureComponents CC)
Result of a PointerMayBeCaptured query, which includes the captured components for both the case wher...
CaptureComponents WithoutRet
CaptureComponents WithRet
This callback is used in conjunction with PointerMayBeCaptured.
virtual bool shouldExplore(const Use *U)
shouldExplore - This is the use of a value derived from the pointer.
@ ContinueIgnoringReturn
Continue traversal, but do not follow the return value of the user, even if it has additional capture...
@ Continue
Continue traversal, and also follow the return value of the user if it has additional capture compone...
@ Stop
Stop the traversal.
virtual Action captured(const Use *U, UseCaptureInfo CI)=0
Use U directly captures CI.UseCC and additionally CI.ResultCC through the return value of the user of...
virtual void tooManyUses()=0
tooManyUses - The depth of traversal has breached a limit.
virtual ~CaptureTracker()
Capture information for a specific Use.
CaptureComponents UseCC
Components captured by this use.
CaptureComponents ResultCC
Components captured by the return value of the user of this Use.
static UseCaptureInfo passthrough()