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