33 #define DEBUG_TYPE "capture-tracking" 35 STATISTIC(NumCaptured,
"Number of pointers maybe captured");
36 STATISTIC(NumNotCaptured,
"Number of pointers not captured");
37 STATISTIC(NumCapturedBefore,
"Number of pointers maybe captured before");
38 STATISTIC(NumNotCapturedBefore,
"Number of pointers not captured before");
48 cl::desc(
"Maximal number of uses to explore."),
68 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
O))
69 if (
GEP->isInBounds())
72 return O->getPointerDereferenceableBytes(
DL, CanBeNull);
77 explicit SimpleCaptureTracker(
bool ReturnCaptures)
78 : ReturnCaptures(ReturnCaptures), Captured(
false) {}
80 void tooManyUses()
override { Captured =
true; }
82 bool captured(
const Use *U)
override {
83 if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
103 : BeforeHere(
I), DT(DT),
104 ReturnCaptures(ReturnCaptures), IncludeI(IncludeI), Captured(
false) {}
106 void tooManyUses()
override { Captured =
true; }
112 if (BeforeHere !=
I && !DT->isReachableFromEntry(BB))
117 if (BB == BeforeHere->getParent()) {
124 if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(
I) ||
I == BeforeHere)
126 if (!BeforeHere->comesBefore(
I))
147 if (BeforeHere !=
I && DT->dominates(BeforeHere,
I) &&
154 bool shouldExplore(
const Use *U)
override {
157 if (BeforeHere ==
I && !IncludeI)
160 if (isSafeToPrune(
I))
166 bool captured(
const Use *U)
override {
167 if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
192 bool ReturnCaptures,
bool StoreCaptures,
193 unsigned MaxUsesToExplore) {
194 assert(!isa<GlobalValue>(V) &&
195 "It doesn't make sense to ask whether a global is captured.");
203 SimpleCaptureTracker SCT(ReturnCaptures);
224 unsigned MaxUsesToExplore) {
225 assert(!isa<GlobalValue>(V) &&
226 "It doesn't make sense to ask whether a global is captured.");
235 CapturesBefore CB(ReturnCaptures,
I, DT, IncludeI);
240 ++NumNotCapturedBefore;
245 unsigned MaxUsesToExplore) {
247 if (MaxUsesToExplore == 0)
254 auto AddUses = [&](
const Value *V) {
256 for (
const Use &U : V->
uses()) {
259 if (Count++ >= MaxUsesToExplore) {
263 if (!Visited.
insert(&U).second)
274 while (!Worklist.
empty()) {
278 switch (
I->getOpcode()) {
280 case Instruction::Invoke: {
281 auto *Call = cast<CallBase>(
I);
285 if (Call->onlyReadsMemory() && Call->doesNotThrow() &&
286 Call->getType()->isVoidTy())
303 if (
auto *
MI = dyn_cast<MemIntrinsic>(Call))
304 if (
MI->isVolatile())
315 if (Call->isDataOperand(U) &&
316 !Call->doesNotCapture(Call->getDataOperandNo(U))) {
325 if (cast<LoadInst>(
I)->isVolatile())
329 case Instruction::VAArg:
335 if (U->getOperandNo() == 0 || cast<StoreInst>(
I)->isVolatile())
339 case Instruction::AtomicRMW: {
345 auto *ARMWI = cast<AtomicRMWInst>(
I);
346 if (U->getOperandNo() == 1 || ARMWI->isVolatile())
351 case Instruction::AtomicCmpXchg: {
357 auto *ACXI = cast<AtomicCmpXchgInst>(
I);
358 if (U->getOperandNo() == 1 || U->getOperandNo() == 2 ||
364 case Instruction::BitCast:
365 case Instruction::GetElementPtr:
366 case Instruction::PHI:
368 case Instruction::AddrSpaceCast:
373 case Instruction::ICmp: {
374 unsigned Idx = U->getOperandNo();
375 unsigned OtherIdx = 1 - Idx;
376 if (
auto *CPN = dyn_cast<ConstantPointerNull>(
I->getOperand(OtherIdx))) {
380 if (CPN->getType()->getAddressSpace() == 0)
383 if (!
I->getFunction()->nullPointerIsDefined()) {
384 auto *
O =
I->getOperand(Idx)->stripPointerCastsSameRepresentation();
395 auto *LI = dyn_cast<LoadInst>(
I->getOperand(OtherIdx));
396 if (LI && isa<GlobalVariable>(LI->getPointerOperand()))
418 if (IsCapturedCache) {
420 std::tie(CacheIt, Inserted) = IsCapturedCache->
insert({V,
false});
423 return CacheIt->second;
435 CacheIt->second =
Ret;
442 if (
const Argument *A = dyn_cast<Argument>(V))
443 if (A->hasByValAttr() || A->hasNoAliasAttr()) {
449 CacheIt->second =
Ret;
bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, const DominatorTree *DT, bool IncludeI=false, unsigned MaxUsesToExplore=0)
PointerMayBeCapturedBefore - Return true if this pointer value may be captured by the enclosing funct...
A parsed version of the target data layout string in and methods for querying it.
iterator_range< use_iterator > uses()
This class represents an incoming formal argument to a Function.
virtual void tooManyUses()=0
tooManyUses - The depth of traversal has breached a limit.
This callback is used in conjunction with PointerMayBeCaptured.
This class represents lattice values for constants.
LLVM_NODISCARD bool empty() const
void push_back(const T &Elt)
virtual bool shouldExplore(const Use *U)
shouldExplore - This is the use of a value derived from the pointer.
STATISTIC(NumFunctions, "Total number of functions")
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void reserve(size_type N)
virtual ~CaptureTracker()
bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
virtual bool isDereferenceableOrNull(Value *O, const DataLayout &DL)
isDereferenceableOrNull - Overload to allow clients with additional knowledge about pointer dereferen...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Use represents the edge between a Value definition and its users.
virtual bool captured(const Use *U)=0
captured - Information about the pointer was captured by the user of use U.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
Type * getType() const
All values are typed, get the type of this value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
bool isNonEscapingLocalObject(const Value *V, SmallDenseMap< const Value *, bool, 8 > *IsCapturedCache=nullptr)
Returns true if the pointer is to a function-local object that never escapes from the function.
Interval::succ_iterator succ_end(Interval *I)
const BasicBlock & getEntryBlock() const
initializer< Ty > init(const Ty &Val)
LLVM Basic Block Representation.
unsigned getDefaultMaxUsesToExploreForCaptureTracking()
getDefaultMaxUsesToExploreForCaptureTracking - Return default value of the maximal number of uses to ...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_NODISCARD T pop_back_val()
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
const Function * getParent() const
Return the enclosing method, or null if none.
static cl::opt< unsigned > DefaultMaxUsesToExplore("capture-tracking-max-uses-to-explore", cl::Hidden, cl::desc("Maximal number of uses to explore."), cl::init(20))
The default value for MaxUsesToExplore argument.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
bool isPotentiallyReachableFromMany(SmallVectorImpl< BasicBlock * > &Worklist, BasicBlock *StopBB, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether there is at least one path from a block in 'Worklist' to 'StopBB',...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL