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 : ReturnCaptures(ReturnCaptures), Mask(Mask), StopFn(StopFn) {}
64 void tooManyUses()
override {
70 if (isa<ReturnInst>(
U->getUser()) && !ReturnCaptures)
71 return ContinueIgnoringReturn;
94 CapturesBefore(
bool ReturnCaptures,
const Instruction *
I,
98 : BeforeHere(
I), DT(DT), ReturnCaptures(ReturnCaptures),
99 IncludeI(IncludeI), LI(LI),
Mask(
Mask), StopFn(StopFn) {}
101 void tooManyUses()
override { CC =
Mask; }
118 if (isa<ReturnInst>(
I) && !ReturnCaptures)
119 return ContinueIgnoringReturn;
124 if (isSafeToPrune(
I))
126 return ContinueIgnoringReturn;
132 return StopFn(CC) ? Stop :
Continue;
160 : DT(DT), ReturnCaptures(ReturnCaptures),
F(
F),
Mask(
Mask) {}
162 void tooManyUses()
override {
164 EarliestCapture = &*
F.getEntryBlock().begin();
169 if (isa<ReturnInst>(
I) && !ReturnCaptures)
170 return ContinueIgnoringReturn;
173 if (!EarliestCapture)
197 assert(!isa<GlobalValue>(V) &&
198 "It doesn't make sense to ask whether a global is captured.");
202 SimpleCaptureTracker SCT(ReturnCaptures, Mask, StopFn);
214 unsigned MaxUsesToExplore) {
224 unsigned MaxUsesToExplore) {
225 assert(!isa<GlobalValue>(V) &&
226 "It doesn't make sense to ask whether a global is captured.");
232 CapturesBefore CB(ReturnCaptures,
I, DT, IncludeI, LI, Mask, StopFn);
237 ++NumNotCapturedBefore;
244 unsigned MaxUsesToExplore,
251std::pair<Instruction *, CaptureComponents>
254 unsigned MaxUsesToExplore) {
255 assert(!isa<GlobalValue>(V) &&
256 "It doesn't make sense to ask whether a global is captured.");
258 EarliestCaptures CB(ReturnCaptures,
F, DT, Mask);
263 ++NumNotCapturedBefore;
264 return {CB.EarliestCapture, CB.CC};
274 switch (
I->getOpcode()) {
275 case Instruction::Call:
276 case Instruction::Invoke: {
277 auto *Call = cast<CallBase>(
I);
281 if (Call->onlyReadsMemory() && Call->doesNotThrow() && Call->willReturn() &&
282 Call->getType()->isVoidTy())
295 if (
auto *
MI = dyn_cast<MemIntrinsic>(Call))
296 if (
MI->isVolatile())
305 if (Call->isCallee(&U))
309 assert(Call->isDataOperand(&U) &&
"Non-callee must be data operand");
310 CaptureInfo CI = Call->getCaptureInfo(Call->getDataOperandNo(&U));
313 case Instruction::Load:
315 if (cast<LoadInst>(
I)->isVolatile())
318 case Instruction::VAArg:
321 case Instruction::Store:
324 if (U.getOperandNo() == 0 || cast<StoreInst>(
I)->isVolatile())
327 case Instruction::AtomicRMW: {
333 auto *ARMWI = cast<AtomicRMWInst>(
I);
334 if (U.getOperandNo() == 1 || ARMWI->isVolatile())
338 case Instruction::AtomicCmpXchg: {
344 auto *ACXI = cast<AtomicCmpXchgInst>(
I);
345 if (U.getOperandNo() == 1 || U.getOperandNo() == 2 || ACXI->isVolatile())
349 case Instruction::GetElementPtr:
352 if (
I->getType()->isVectorTy())
355 case Instruction::BitCast:
356 case Instruction::PHI:
357 case Instruction::Select:
358 case Instruction::AddrSpaceCast:
361 case Instruction::PtrToAddr:
367 case Instruction::ICmp: {
368 unsigned Idx = U.getOperandNo();
369 unsigned OtherIdx = 1 -
Idx;
370 if (isa<ConstantPointerNull>(
I->getOperand(OtherIdx)) &&
371 cast<ICmpInst>(
I)->isEquality()) {
378 if (U->getType()->getPointerAddressSpace() == 0)
400 unsigned MaxUsesToExplore) {
401 assert(V->getType()->isPointerTy() &&
"Capture is for pointers only!");
402 if (MaxUsesToExplore == 0)
409 auto AddUses = [&](
const Value *V) {
410 for (
const Use &U : V->uses()) {
413 if (Visited.
size() >= MaxUsesToExplore) {
417 if (!Visited.
insert(&U).second)
428 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...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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...
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.
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)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::pair< Instruction *, CaptureComponents > FindEarliestCapture(const Value *V, Function &F, bool ReturnCaptures, const DominatorTree &DT, CaptureComponents Mask, unsigned MaxUsesToExplore=0)
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.
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...
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)
LLVM_ABI 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 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()