39 explicit SimpleCaptureTracker(
bool ReturnCaptures)
40 : ReturnCaptures(ReturnCaptures), Captured(
false) {}
42 void tooManyUses()
override { Captured =
true; }
44 bool captured(
const Use *U)
override {
45 if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
65 : OrderedBB(IC), BeforeHere(I), DT(DT),
66 ReturnCaptures(ReturnCaptures), IncludeI(IncludeI), Captured(
false) {}
68 void tooManyUses()
override { Captured =
true; }
74 if (BeforeHere != I && !DT->isReachableFromEntry(BB))
88 if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(
I) || I == BeforeHere)
90 if (!OrderedBB->dominates(BeforeHere, I))
111 if (BeforeHere != I && DT->dominates(BeforeHere, I) &&
118 bool shouldExplore(
const Use *U)
override {
121 if (BeforeHere == I && !IncludeI)
124 if (isSafeToPrune(I))
130 bool captured(
const Use *U)
override {
131 if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
134 if (!shouldExplore(U))
160 bool ReturnCaptures,
bool StoreCaptures) {
161 assert(!isa<GlobalValue>(V) &&
162 "It doesn't make sense to ask whether a global is captured.");
170 SimpleCaptureTracker SCT(ReturnCaptures);
189 assert(!isa<GlobalValue>(V) &&
190 "It doesn't make sense to ask whether a global is captured.");
191 bool UseNewOBB = OBB ==
nullptr;
201 CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB);
220 for (
const Use &U : V->
uses()) {
228 Worklist.push_back(&U);
231 while (!Worklist.empty()) {
232 const Use *U = Worklist.pop_back_val();
238 case Instruction::Invoke: {
248 if (
auto *
MI = dyn_cast<MemIntrinsic>(I))
249 if (
MI->isVolatile())
271 if (cast<LoadInst>(I)->isVolatile())
275 case Instruction::VAArg:
285 case Instruction::AtomicRMW: {
291 auto *ARMWI = cast<AtomicRMWInst>(
I);
292 if (ARMWI->getValOperand() == V || ARMWI->isVolatile())
297 case Instruction::AtomicCmpXchg: {
303 auto *ACXI = cast<AtomicCmpXchgInst>(
I);
304 if (ACXI->getCompareOperand() == V || ACXI->getNewValOperand() == V ||
310 case Instruction::BitCast:
311 case Instruction::GetElementPtr:
312 case Instruction::PHI:
314 case Instruction::AddrSpaceCast:
323 if (Visited.
insert(&UU).second)
325 Worklist.push_back(&UU);
328 case Instruction::ICmp: {
333 dyn_cast<ConstantPointerNull>(I->
getOperand(1)))
334 if (CPN->getType()->getAddressSpace() == 0)
340 unsigned OtherIndex = (I->
getOperand(0) == V) ? 1 : 0;
342 if (LI && isa<GlobalVariable>(LI->getPointerOperand()))
iterator_range< use_iterator > uses()
virtual void tooManyUses()=0
tooManyUses - The depth of traversal has breached a limit.
This callback is used in conjunction with PointerMayBeCaptured.
bool doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
virtual bool shouldExplore(const Use *U)
shouldExplore - This is the use of a value derived from the pointer.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
An instruction for reading from memory.
virtual ~CaptureTracker()
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...
IterTy data_operands_begin() const
data_operands_begin/data_operands_end - Return iterators iterating over the call / invoke argument li...
Function Alias Analysis false
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
LLVM Basic Block Representation.
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...
Value * getOperand(unsigned i) const
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', returning true if uncertain.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
bool isPointerTy() const
True if this is an instance of PointerType.
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
A constant pointer value that points to null.
const BasicBlock & getEntryBlock() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, DominatorTree *DT, bool IncludeI=false, OrderedBasicBlock *OBB=nullptr)
PointerMayBeCapturedBefore - Return true if this pointer value may be captured by the enclosing funct...
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
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', returning true if uncertain.
static bool isVolatile(Instruction *Inst)
IterTy data_operands_end() const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const BasicBlock * getParent() const
bool doesNotThrow() const
Determine if the call cannot unwind.
bool isVoidTy() const
Return true if this is 'void'.