xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/CaptureTracking.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- CaptureTracking.cpp - Determine whether a pointer is captured ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains routines that help determine which pointers are captured.
100b57cec5SDimitry Andric // A pointer value is captured if the function makes a copy of any part of the
110b57cec5SDimitry Andric // pointer that outlives the call.  Not being captured means, more or less, that
120b57cec5SDimitry Andric // the pointer is only dereferenced and not stored in a global.  Returning part
130b57cec5SDimitry Andric // of the pointer as the function return value may or may not count as capturing
140b57cec5SDimitry Andric // the pointer, depending on the context.
150b57cec5SDimitry Andric //
160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/Analysis/CaptureTracking.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
21e8d8bef9SDimitry Andric #include "llvm/ADT/Statistic.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/CFG.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
250b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
260b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
270b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
280b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
295ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace llvm;
320b57cec5SDimitry Andric 
33e8d8bef9SDimitry Andric #define DEBUG_TYPE "capture-tracking"
34e8d8bef9SDimitry Andric 
35e8d8bef9SDimitry Andric STATISTIC(NumCaptured,          "Number of pointers maybe captured");
36e8d8bef9SDimitry Andric STATISTIC(NumNotCaptured,       "Number of pointers not captured");
37e8d8bef9SDimitry Andric STATISTIC(NumCapturedBefore,    "Number of pointers maybe captured before");
38e8d8bef9SDimitry Andric STATISTIC(NumNotCapturedBefore, "Number of pointers not captured before");
39e8d8bef9SDimitry Andric 
405ffd83dbSDimitry Andric /// The default value for MaxUsesToExplore argument. It's relatively small to
415ffd83dbSDimitry Andric /// keep the cost of analysis reasonable for clients like BasicAliasAnalysis,
425ffd83dbSDimitry Andric /// where the results can't be cached.
435ffd83dbSDimitry Andric /// TODO: we should probably introduce a caching CaptureTracking analysis and
445ffd83dbSDimitry Andric /// use it where possible. The caching version can use much higher limit or
455ffd83dbSDimitry Andric /// don't have this cap at all.
465ffd83dbSDimitry Andric static cl::opt<unsigned>
475ffd83dbSDimitry Andric     DefaultMaxUsesToExplore("capture-tracking-max-uses-to-explore", cl::Hidden,
485ffd83dbSDimitry Andric                             cl::desc("Maximal number of uses to explore."),
4981ad6265SDimitry Andric                             cl::init(100));
505ffd83dbSDimitry Andric 
515ffd83dbSDimitry Andric unsigned llvm::getDefaultMaxUsesToExploreForCaptureTracking() {
525ffd83dbSDimitry Andric   return DefaultMaxUsesToExplore;
535ffd83dbSDimitry Andric }
545ffd83dbSDimitry Andric 
5581ad6265SDimitry Andric CaptureTracker::~CaptureTracker() = default;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric bool CaptureTracker::shouldExplore(const Use *U) { return true; }
580b57cec5SDimitry Andric 
598bcb0991SDimitry Andric bool CaptureTracker::isDereferenceableOrNull(Value *O, const DataLayout &DL) {
6006c3fb27SDimitry Andric   // We want comparisons to null pointers to not be considered capturing,
6106c3fb27SDimitry Andric   // but need to guard against cases like gep(p, -ptrtoint(p2)) == null,
6206c3fb27SDimitry Andric   // which are equivalent to p == p2 and would capture the pointer.
6306c3fb27SDimitry Andric   //
6406c3fb27SDimitry Andric   // A dereferenceable pointer is a case where this is known to be safe,
6506c3fb27SDimitry Andric   // because the pointer resulting from such a construction would not be
6606c3fb27SDimitry Andric   // dereferenceable.
6706c3fb27SDimitry Andric   //
6806c3fb27SDimitry Andric   // It is not sufficient to check for inbounds GEP here, because GEP with
6906c3fb27SDimitry Andric   // zero offset is always inbounds.
70fe6060f1SDimitry Andric   bool CanBeNull, CanBeFreed;
71fe6060f1SDimitry Andric   return O->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
728bcb0991SDimitry Andric }
738bcb0991SDimitry Andric 
740b57cec5SDimitry Andric namespace {
750b57cec5SDimitry Andric struct SimpleCaptureTracker : public CaptureTracker {
765f757f3fSDimitry Andric   explicit SimpleCaptureTracker(bool ReturnCaptures)
775f757f3fSDimitry Andric       : ReturnCaptures(ReturnCaptures) {}
780b57cec5SDimitry Andric 
7906c3fb27SDimitry Andric   void tooManyUses() override {
8006c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "Captured due to too many uses\n");
8106c3fb27SDimitry Andric     Captured = true;
8206c3fb27SDimitry Andric   }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   bool captured(const Use *U) override {
850b57cec5SDimitry Andric     if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
860b57cec5SDimitry Andric       return false;
870b57cec5SDimitry Andric 
8806c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "Captured by: " << *U->getUser() << "\n");
8906c3fb27SDimitry Andric 
900b57cec5SDimitry Andric     Captured = true;
910b57cec5SDimitry Andric     return true;
920b57cec5SDimitry Andric   }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   bool ReturnCaptures;
950b57cec5SDimitry Andric 
9604eeddc0SDimitry Andric   bool Captured = false;
970b57cec5SDimitry Andric };
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric /// Only find pointer captures which happen before the given instruction. Uses
1000b57cec5SDimitry Andric /// the dominator tree to determine whether one instruction is before another.
1010b57cec5SDimitry Andric /// Only support the case where the Value is defined in the same basic block
1020b57cec5SDimitry Andric /// as the given instruction and the use.
1030b57cec5SDimitry Andric struct CapturesBefore : public CaptureTracker {
1040b57cec5SDimitry Andric 
105349cc55cSDimitry Andric   CapturesBefore(bool ReturnCaptures, const Instruction *I,
106349cc55cSDimitry Andric                  const DominatorTree *DT, bool IncludeI, const LoopInfo *LI)
107349cc55cSDimitry Andric       : BeforeHere(I), DT(DT), ReturnCaptures(ReturnCaptures),
10804eeddc0SDimitry Andric         IncludeI(IncludeI), LI(LI) {}
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   void tooManyUses() override { Captured = true; }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   bool isSafeToPrune(Instruction *I) {
113fe6060f1SDimitry Andric     if (BeforeHere == I)
114fe6060f1SDimitry Andric       return !IncludeI;
115fe6060f1SDimitry Andric 
1160b57cec5SDimitry Andric     // We explore this usage only if the usage can reach "BeforeHere".
1170b57cec5SDimitry Andric     // If use is not reachable from entry, there is no need to explore.
118fe6060f1SDimitry Andric     if (!DT->isReachableFromEntry(I->getParent()))
1190b57cec5SDimitry Andric       return true;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric     // Check whether there is a path from I to BeforeHere.
122349cc55cSDimitry Andric     return !isPotentiallyReachable(I, BeforeHere, nullptr, DT, LI);
1230b57cec5SDimitry Andric   }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   bool captured(const Use *U) override {
126fe6060f1SDimitry Andric     Instruction *I = cast<Instruction>(U->getUser());
127fe6060f1SDimitry Andric     if (isa<ReturnInst>(I) && !ReturnCaptures)
128fe6060f1SDimitry Andric       return false;
129fe6060f1SDimitry Andric 
130fe6060f1SDimitry Andric     // Check isSafeToPrune() here rather than in shouldExplore() to avoid
131fe6060f1SDimitry Andric     // an expensive reachability query for every instruction we look at.
132fe6060f1SDimitry Andric     // Instead we only do one for actual capturing candidates.
133fe6060f1SDimitry Andric     if (isSafeToPrune(I))
1340b57cec5SDimitry Andric       return false;
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric     Captured = true;
1370b57cec5SDimitry Andric     return true;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   const Instruction *BeforeHere;
1410b57cec5SDimitry Andric   const DominatorTree *DT;
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   bool ReturnCaptures;
1440b57cec5SDimitry Andric   bool IncludeI;
1450b57cec5SDimitry Andric 
14604eeddc0SDimitry Andric   bool Captured = false;
147349cc55cSDimitry Andric 
148349cc55cSDimitry Andric   const LoopInfo *LI;
149349cc55cSDimitry Andric };
150349cc55cSDimitry Andric 
151349cc55cSDimitry Andric /// Find the 'earliest' instruction before which the pointer is known not to
152349cc55cSDimitry Andric /// be captured. Here an instruction A is considered earlier than instruction
153349cc55cSDimitry Andric /// B, if A dominates B. If 2 escapes do not dominate each other, the
154349cc55cSDimitry Andric /// terminator of the common dominator is chosen. If not all uses cannot be
155349cc55cSDimitry Andric /// analyzed, the earliest escape is set to the first instruction in the
156349cc55cSDimitry Andric /// function entry block.
157349cc55cSDimitry Andric // NOTE: Users have to make sure instructions compared against the earliest
158349cc55cSDimitry Andric // escape are not in a cycle.
159349cc55cSDimitry Andric struct EarliestCaptures : public CaptureTracker {
160349cc55cSDimitry Andric 
1615f757f3fSDimitry Andric   EarliestCaptures(bool ReturnCaptures, Function &F, const DominatorTree &DT)
1625f757f3fSDimitry Andric       : DT(DT), ReturnCaptures(ReturnCaptures), F(F) {}
163349cc55cSDimitry Andric 
164349cc55cSDimitry Andric   void tooManyUses() override {
165349cc55cSDimitry Andric     Captured = true;
166349cc55cSDimitry Andric     EarliestCapture = &*F.getEntryBlock().begin();
167349cc55cSDimitry Andric   }
168349cc55cSDimitry Andric 
169349cc55cSDimitry Andric   bool captured(const Use *U) override {
170349cc55cSDimitry Andric     Instruction *I = cast<Instruction>(U->getUser());
171349cc55cSDimitry Andric     if (isa<ReturnInst>(I) && !ReturnCaptures)
172349cc55cSDimitry Andric       return false;
173349cc55cSDimitry Andric 
174bdd1243dSDimitry Andric     if (!EarliestCapture)
175349cc55cSDimitry Andric       EarliestCapture = I;
176bdd1243dSDimitry Andric     else
177bdd1243dSDimitry Andric       EarliestCapture = DT.findNearestCommonDominator(EarliestCapture, I);
178349cc55cSDimitry Andric     Captured = true;
179349cc55cSDimitry Andric 
180349cc55cSDimitry Andric     // Return false to continue analysis; we need to see all potential
181349cc55cSDimitry Andric     // captures.
182349cc55cSDimitry Andric     return false;
183349cc55cSDimitry Andric   }
184349cc55cSDimitry Andric 
185349cc55cSDimitry Andric   Instruction *EarliestCapture = nullptr;
186349cc55cSDimitry Andric 
187349cc55cSDimitry Andric   const DominatorTree &DT;
188349cc55cSDimitry Andric 
189349cc55cSDimitry Andric   bool ReturnCaptures;
190349cc55cSDimitry Andric 
19104eeddc0SDimitry Andric   bool Captured = false;
192349cc55cSDimitry Andric 
193349cc55cSDimitry Andric   Function &F;
1940b57cec5SDimitry Andric };
195*0fca6ea1SDimitry Andric } // namespace
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric /// PointerMayBeCaptured - Return true if this pointer value may be captured
1980b57cec5SDimitry Andric /// by the enclosing function (which is required to exist).  This routine can
1990b57cec5SDimitry Andric /// be expensive, so consider caching the results.  The boolean ReturnCaptures
2000b57cec5SDimitry Andric /// specifies whether returning the value (or part of it) from the function
2010b57cec5SDimitry Andric /// counts as capturing it or not.  The boolean StoreCaptures specified whether
2020b57cec5SDimitry Andric /// storing the value (or part of it) into memory anywhere automatically
2030b57cec5SDimitry Andric /// counts as capturing it or not.
20481ad6265SDimitry Andric bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures,
20581ad6265SDimitry Andric                                 bool StoreCaptures, unsigned MaxUsesToExplore) {
2060b57cec5SDimitry Andric   assert(!isa<GlobalValue>(V) &&
2070b57cec5SDimitry Andric          "It doesn't make sense to ask whether a global is captured.");
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   // TODO: If StoreCaptures is not true, we could do Fancy analysis
2100b57cec5SDimitry Andric   // to determine whether this store is not actually an escape point.
2110b57cec5SDimitry Andric   // In that case, BasicAliasAnalysis should be updated as well to
2120b57cec5SDimitry Andric   // take advantage of this.
2130b57cec5SDimitry Andric   (void)StoreCaptures;
2140b57cec5SDimitry Andric 
21506c3fb27SDimitry Andric   LLVM_DEBUG(dbgs() << "Captured?: " << *V << " = ");
21606c3fb27SDimitry Andric 
2175f757f3fSDimitry Andric   SimpleCaptureTracker SCT(ReturnCaptures);
2180b57cec5SDimitry Andric   PointerMayBeCaptured(V, &SCT, MaxUsesToExplore);
219e8d8bef9SDimitry Andric   if (SCT.Captured)
220e8d8bef9SDimitry Andric     ++NumCaptured;
22106c3fb27SDimitry Andric   else {
222e8d8bef9SDimitry Andric     ++NumNotCaptured;
22306c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "not captured\n");
22406c3fb27SDimitry Andric   }
2250b57cec5SDimitry Andric   return SCT.Captured;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric /// PointerMayBeCapturedBefore - Return true if this pointer value may be
2290b57cec5SDimitry Andric /// captured by the enclosing function (which is required to exist). If a
2300b57cec5SDimitry Andric /// DominatorTree is provided, only captures which happen before the given
2310b57cec5SDimitry Andric /// instruction are considered. This routine can be expensive, so consider
2320b57cec5SDimitry Andric /// caching the results.  The boolean ReturnCaptures specifies whether
2330b57cec5SDimitry Andric /// returning the value (or part of it) from the function counts as capturing
2340b57cec5SDimitry Andric /// it or not.  The boolean StoreCaptures specified whether storing the value
2350b57cec5SDimitry Andric /// (or part of it) into memory anywhere automatically counts as capturing it
2365ffd83dbSDimitry Andric /// or not.
2370b57cec5SDimitry Andric bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
2380b57cec5SDimitry Andric                                       bool StoreCaptures, const Instruction *I,
2390b57cec5SDimitry Andric                                       const DominatorTree *DT, bool IncludeI,
240349cc55cSDimitry Andric                                       unsigned MaxUsesToExplore,
241349cc55cSDimitry Andric                                       const LoopInfo *LI) {
2420b57cec5SDimitry Andric   assert(!isa<GlobalValue>(V) &&
2430b57cec5SDimitry Andric          "It doesn't make sense to ask whether a global is captured.");
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   if (!DT)
2460b57cec5SDimitry Andric     return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures,
2470b57cec5SDimitry Andric                                 MaxUsesToExplore);
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   // TODO: See comment in PointerMayBeCaptured regarding what could be done
2500b57cec5SDimitry Andric   // with StoreCaptures.
2510b57cec5SDimitry Andric 
252349cc55cSDimitry Andric   CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, LI);
2530b57cec5SDimitry Andric   PointerMayBeCaptured(V, &CB, MaxUsesToExplore);
254e8d8bef9SDimitry Andric   if (CB.Captured)
255e8d8bef9SDimitry Andric     ++NumCapturedBefore;
256e8d8bef9SDimitry Andric   else
257e8d8bef9SDimitry Andric     ++NumNotCapturedBefore;
2580b57cec5SDimitry Andric   return CB.Captured;
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2615f757f3fSDimitry Andric Instruction *llvm::FindEarliestCapture(const Value *V, Function &F,
2625f757f3fSDimitry Andric                                        bool ReturnCaptures, bool StoreCaptures,
2635f757f3fSDimitry Andric                                        const DominatorTree &DT,
264349cc55cSDimitry Andric                                        unsigned MaxUsesToExplore) {
265349cc55cSDimitry Andric   assert(!isa<GlobalValue>(V) &&
266349cc55cSDimitry Andric          "It doesn't make sense to ask whether a global is captured.");
267349cc55cSDimitry Andric 
2685f757f3fSDimitry Andric   EarliestCaptures CB(ReturnCaptures, F, DT);
269349cc55cSDimitry Andric   PointerMayBeCaptured(V, &CB, MaxUsesToExplore);
270349cc55cSDimitry Andric   if (CB.Captured)
271349cc55cSDimitry Andric     ++NumCapturedBefore;
272349cc55cSDimitry Andric   else
273349cc55cSDimitry Andric     ++NumNotCapturedBefore;
274349cc55cSDimitry Andric   return CB.EarliestCapture;
275349cc55cSDimitry Andric }
276349cc55cSDimitry Andric 
27781ad6265SDimitry Andric UseCaptureKind llvm::DetermineUseCaptureKind(
27881ad6265SDimitry Andric     const Use &U,
27981ad6265SDimitry Andric     function_ref<bool(Value *, const DataLayout &)> IsDereferenceableOrNull) {
2805f757f3fSDimitry Andric   Instruction *I = dyn_cast<Instruction>(U.getUser());
2815f757f3fSDimitry Andric 
2825f757f3fSDimitry Andric   // TODO: Investigate non-instruction uses.
2835f757f3fSDimitry Andric   if (!I)
2845f757f3fSDimitry Andric     return UseCaptureKind::MAY_CAPTURE;
28581ad6265SDimitry Andric 
28681ad6265SDimitry Andric   switch (I->getOpcode()) {
28781ad6265SDimitry Andric   case Instruction::Call:
28881ad6265SDimitry Andric   case Instruction::Invoke: {
28981ad6265SDimitry Andric     auto *Call = cast<CallBase>(I);
29081ad6265SDimitry Andric     // Not captured if the callee is readonly, doesn't return a copy through
29181ad6265SDimitry Andric     // its return value and doesn't unwind (a readonly function can leak bits
29281ad6265SDimitry Andric     // by throwing an exception or not depending on the input value).
29381ad6265SDimitry Andric     if (Call->onlyReadsMemory() && Call->doesNotThrow() &&
29481ad6265SDimitry Andric         Call->getType()->isVoidTy())
29581ad6265SDimitry Andric       return UseCaptureKind::NO_CAPTURE;
29681ad6265SDimitry Andric 
29781ad6265SDimitry Andric     // The pointer is not captured if returned pointer is not captured.
29881ad6265SDimitry Andric     // NOTE: CaptureTracking users should not assume that only functions
29981ad6265SDimitry Andric     // marked with nocapture do not capture. This means that places like
30081ad6265SDimitry Andric     // getUnderlyingObject in ValueTracking or DecomposeGEPExpression
30181ad6265SDimitry Andric     // in BasicAA also need to know about this property.
30281ad6265SDimitry Andric     if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(Call, true))
30381ad6265SDimitry Andric       return UseCaptureKind::PASSTHROUGH;
30481ad6265SDimitry Andric 
30581ad6265SDimitry Andric     // Volatile operations effectively capture the memory location that they
30681ad6265SDimitry Andric     // load and store to.
30781ad6265SDimitry Andric     if (auto *MI = dyn_cast<MemIntrinsic>(Call))
30881ad6265SDimitry Andric       if (MI->isVolatile())
30981ad6265SDimitry Andric         return UseCaptureKind::MAY_CAPTURE;
31081ad6265SDimitry Andric 
31181ad6265SDimitry Andric     // Calling a function pointer does not in itself cause the pointer to
31281ad6265SDimitry Andric     // be captured.  This is a subtle point considering that (for example)
31381ad6265SDimitry Andric     // the callee might return its own address.  It is analogous to saying
31481ad6265SDimitry Andric     // that loading a value from a pointer does not cause the pointer to be
31581ad6265SDimitry Andric     // captured, even though the loaded value might be the pointer itself
31681ad6265SDimitry Andric     // (think of self-referential objects).
31781ad6265SDimitry Andric     if (Call->isCallee(&U))
31881ad6265SDimitry Andric       return UseCaptureKind::NO_CAPTURE;
31981ad6265SDimitry Andric 
32081ad6265SDimitry Andric     // Not captured if only passed via 'nocapture' arguments.
32181ad6265SDimitry Andric     if (Call->isDataOperand(&U) &&
32281ad6265SDimitry Andric         !Call->doesNotCapture(Call->getDataOperandNo(&U))) {
32381ad6265SDimitry Andric       // The parameter is not marked 'nocapture' - captured.
32481ad6265SDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
32581ad6265SDimitry Andric     }
32681ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
32781ad6265SDimitry Andric   }
32881ad6265SDimitry Andric   case Instruction::Load:
32981ad6265SDimitry Andric     // Volatile loads make the address observable.
33081ad6265SDimitry Andric     if (cast<LoadInst>(I)->isVolatile())
33181ad6265SDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
33281ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
33381ad6265SDimitry Andric   case Instruction::VAArg:
33481ad6265SDimitry Andric     // "va-arg" from a pointer does not cause it to be captured.
33581ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
33681ad6265SDimitry Andric   case Instruction::Store:
33781ad6265SDimitry Andric     // Stored the pointer - conservatively assume it may be captured.
33881ad6265SDimitry Andric     // Volatile stores make the address observable.
33981ad6265SDimitry Andric     if (U.getOperandNo() == 0 || cast<StoreInst>(I)->isVolatile())
34081ad6265SDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
34181ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
34281ad6265SDimitry Andric   case Instruction::AtomicRMW: {
34381ad6265SDimitry Andric     // atomicrmw conceptually includes both a load and store from
34481ad6265SDimitry Andric     // the same location.
34581ad6265SDimitry Andric     // As with a store, the location being accessed is not captured,
34681ad6265SDimitry Andric     // but the value being stored is.
34781ad6265SDimitry Andric     // Volatile stores make the address observable.
34881ad6265SDimitry Andric     auto *ARMWI = cast<AtomicRMWInst>(I);
34981ad6265SDimitry Andric     if (U.getOperandNo() == 1 || ARMWI->isVolatile())
35081ad6265SDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
35181ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
35281ad6265SDimitry Andric   }
35381ad6265SDimitry Andric   case Instruction::AtomicCmpXchg: {
35481ad6265SDimitry Andric     // cmpxchg conceptually includes both a load and store from
35581ad6265SDimitry Andric     // the same location.
35681ad6265SDimitry Andric     // As with a store, the location being accessed is not captured,
35781ad6265SDimitry Andric     // but the value being stored is.
35881ad6265SDimitry Andric     // Volatile stores make the address observable.
35981ad6265SDimitry Andric     auto *ACXI = cast<AtomicCmpXchgInst>(I);
36081ad6265SDimitry Andric     if (U.getOperandNo() == 1 || U.getOperandNo() == 2 || ACXI->isVolatile())
36181ad6265SDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
36281ad6265SDimitry Andric     return UseCaptureKind::NO_CAPTURE;
36381ad6265SDimitry Andric   }
36481ad6265SDimitry Andric   case Instruction::GetElementPtr:
3655f757f3fSDimitry Andric     // AA does not support pointers of vectors, so GEP vector splats need to
3665f757f3fSDimitry Andric     // be considered as captures.
3675f757f3fSDimitry Andric     if (I->getType()->isVectorTy())
3685f757f3fSDimitry Andric       return UseCaptureKind::MAY_CAPTURE;
3695f757f3fSDimitry Andric     return UseCaptureKind::PASSTHROUGH;
3705f757f3fSDimitry Andric   case Instruction::BitCast:
37181ad6265SDimitry Andric   case Instruction::PHI:
37281ad6265SDimitry Andric   case Instruction::Select:
37381ad6265SDimitry Andric   case Instruction::AddrSpaceCast:
37481ad6265SDimitry Andric     // The original value is not captured via this if the new value isn't.
37581ad6265SDimitry Andric     return UseCaptureKind::PASSTHROUGH;
37681ad6265SDimitry Andric   case Instruction::ICmp: {
37781ad6265SDimitry Andric     unsigned Idx = U.getOperandNo();
37881ad6265SDimitry Andric     unsigned OtherIdx = 1 - Idx;
37981ad6265SDimitry Andric     if (auto *CPN = dyn_cast<ConstantPointerNull>(I->getOperand(OtherIdx))) {
38081ad6265SDimitry Andric       // Don't count comparisons of a no-alias return value against null as
38181ad6265SDimitry Andric       // captures. This allows us to ignore comparisons of malloc results
38281ad6265SDimitry Andric       // with null, for example.
38381ad6265SDimitry Andric       if (CPN->getType()->getAddressSpace() == 0)
38481ad6265SDimitry Andric         if (isNoAliasCall(U.get()->stripPointerCasts()))
38581ad6265SDimitry Andric           return UseCaptureKind::NO_CAPTURE;
38681ad6265SDimitry Andric       if (!I->getFunction()->nullPointerIsDefined()) {
38781ad6265SDimitry Andric         auto *O = I->getOperand(Idx)->stripPointerCastsSameRepresentation();
38881ad6265SDimitry Andric         // Comparing a dereferenceable_or_null pointer against null cannot
38981ad6265SDimitry Andric         // lead to pointer escapes, because if it is not null it must be a
39081ad6265SDimitry Andric         // valid (in-bounds) pointer.
391*0fca6ea1SDimitry Andric         const DataLayout &DL = I->getDataLayout();
39281ad6265SDimitry Andric         if (IsDereferenceableOrNull && IsDereferenceableOrNull(O, DL))
39381ad6265SDimitry Andric           return UseCaptureKind::NO_CAPTURE;
39481ad6265SDimitry Andric       }
39581ad6265SDimitry Andric     }
39606c3fb27SDimitry Andric 
39781ad6265SDimitry Andric     // Otherwise, be conservative. There are crazy ways to capture pointers
39881ad6265SDimitry Andric     // using comparisons.
39981ad6265SDimitry Andric     return UseCaptureKind::MAY_CAPTURE;
40081ad6265SDimitry Andric   }
40181ad6265SDimitry Andric   default:
40281ad6265SDimitry Andric     // Something else - be conservative and say it is captured.
40381ad6265SDimitry Andric     return UseCaptureKind::MAY_CAPTURE;
40481ad6265SDimitry Andric   }
40581ad6265SDimitry Andric }
40681ad6265SDimitry Andric 
4070b57cec5SDimitry Andric void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
4080b57cec5SDimitry Andric                                 unsigned MaxUsesToExplore) {
4090b57cec5SDimitry Andric   assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
4105ffd83dbSDimitry Andric   if (MaxUsesToExplore == 0)
4115ffd83dbSDimitry Andric     MaxUsesToExplore = DefaultMaxUsesToExplore;
4125ffd83dbSDimitry Andric 
4135ffd83dbSDimitry Andric   SmallVector<const Use *, 20> Worklist;
4145ffd83dbSDimitry Andric   Worklist.reserve(getDefaultMaxUsesToExploreForCaptureTracking());
4155ffd83dbSDimitry Andric   SmallSet<const Use *, 20> Visited;
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   auto AddUses = [&](const Value *V) {
4180b57cec5SDimitry Andric     for (const Use &U : V->uses()) {
4190b57cec5SDimitry Andric       // If there are lots of uses, conservatively say that the value
4200b57cec5SDimitry Andric       // is captured to avoid taking too much compile time.
42181ad6265SDimitry Andric       if (Visited.size()  >= MaxUsesToExplore) {
422e8d8bef9SDimitry Andric         Tracker->tooManyUses();
423e8d8bef9SDimitry Andric         return false;
424e8d8bef9SDimitry Andric       }
4250b57cec5SDimitry Andric       if (!Visited.insert(&U).second)
4260b57cec5SDimitry Andric         continue;
4270b57cec5SDimitry Andric       if (!Tracker->shouldExplore(&U))
4280b57cec5SDimitry Andric         continue;
4290b57cec5SDimitry Andric       Worklist.push_back(&U);
4300b57cec5SDimitry Andric     }
431e8d8bef9SDimitry Andric     return true;
4320b57cec5SDimitry Andric   };
433e8d8bef9SDimitry Andric   if (!AddUses(V))
434e8d8bef9SDimitry Andric     return;
4350b57cec5SDimitry Andric 
43681ad6265SDimitry Andric   auto IsDereferenceableOrNull = [Tracker](Value *V, const DataLayout &DL) {
43781ad6265SDimitry Andric     return Tracker->isDereferenceableOrNull(V, DL);
43881ad6265SDimitry Andric   };
4390b57cec5SDimitry Andric   while (!Worklist.empty()) {
4400b57cec5SDimitry Andric     const Use *U = Worklist.pop_back_val();
44181ad6265SDimitry Andric     switch (DetermineUseCaptureKind(*U, IsDereferenceableOrNull)) {
44281ad6265SDimitry Andric     case UseCaptureKind::NO_CAPTURE:
44381ad6265SDimitry Andric       continue;
44481ad6265SDimitry Andric     case UseCaptureKind::MAY_CAPTURE:
4450b57cec5SDimitry Andric       if (Tracker->captured(U))
4460b57cec5SDimitry Andric         return;
44781ad6265SDimitry Andric       continue;
44881ad6265SDimitry Andric     case UseCaptureKind::PASSTHROUGH:
44981ad6265SDimitry Andric       if (!AddUses(U->getUser()))
4500b57cec5SDimitry Andric         return;
45181ad6265SDimitry Andric       continue;
4520b57cec5SDimitry Andric     }
4530b57cec5SDimitry Andric   }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   // All uses examined.
4560b57cec5SDimitry Andric }
457e8d8bef9SDimitry Andric 
458e8d8bef9SDimitry Andric bool llvm::isNonEscapingLocalObject(
459e8d8bef9SDimitry Andric     const Value *V, SmallDenseMap<const Value *, bool, 8> *IsCapturedCache) {
460e8d8bef9SDimitry Andric   SmallDenseMap<const Value *, bool, 8>::iterator CacheIt;
461e8d8bef9SDimitry Andric   if (IsCapturedCache) {
462e8d8bef9SDimitry Andric     bool Inserted;
463e8d8bef9SDimitry Andric     std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false});
464e8d8bef9SDimitry Andric     if (!Inserted)
465e8d8bef9SDimitry Andric       // Found cached result, return it!
466e8d8bef9SDimitry Andric       return CacheIt->second;
467e8d8bef9SDimitry Andric   }
468e8d8bef9SDimitry Andric 
469fe6060f1SDimitry Andric   // If this is an identified function-local object, check to see if it escapes.
470fe6060f1SDimitry Andric   if (isIdentifiedFunctionLocal(V)) {
471e8d8bef9SDimitry Andric     // Set StoreCaptures to True so that we can assume in our callers that the
472e8d8bef9SDimitry Andric     // pointer is not the result of a load instruction. Currently
473e8d8bef9SDimitry Andric     // PointerMayBeCaptured doesn't have any special analysis for the
474e8d8bef9SDimitry Andric     // StoreCaptures=false case; if it did, our callers could be refined to be
475e8d8bef9SDimitry Andric     // more precise.
476e8d8bef9SDimitry Andric     auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true);
477e8d8bef9SDimitry Andric     if (IsCapturedCache)
478e8d8bef9SDimitry Andric       CacheIt->second = Ret;
479e8d8bef9SDimitry Andric     return Ret;
480e8d8bef9SDimitry Andric   }
481e8d8bef9SDimitry Andric 
482e8d8bef9SDimitry Andric   return false;
483e8d8bef9SDimitry Andric }
484