diff options
Diffstat (limited to 'lib/Analysis/CaptureTracking.cpp')
-rw-r--r-- | lib/Analysis/CaptureTracking.cpp | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp index d4f73bdb4361..669f4f2835fa 100644 --- a/lib/Analysis/CaptureTracking.cpp +++ b/lib/Analysis/CaptureTracking.cpp @@ -23,7 +23,6 @@ #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/OrderedBasicBlock.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" @@ -158,7 +157,8 @@ namespace { /// storing the value (or part of it) into memory anywhere automatically /// counts as capturing it or not. bool llvm::PointerMayBeCaptured(const Value *V, - bool ReturnCaptures, bool StoreCaptures) { + bool ReturnCaptures, bool StoreCaptures, + unsigned MaxUsesToExplore) { assert(!isa<GlobalValue>(V) && "It doesn't make sense to ask whether a global is captured."); @@ -169,7 +169,7 @@ bool llvm::PointerMayBeCaptured(const Value *V, (void)StoreCaptures; SimpleCaptureTracker SCT(ReturnCaptures); - PointerMayBeCaptured(V, &SCT); + PointerMayBeCaptured(V, &SCT, MaxUsesToExplore); return SCT.Captured; } @@ -186,13 +186,15 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, const DominatorTree *DT, bool IncludeI, - OrderedBasicBlock *OBB) { + OrderedBasicBlock *OBB, + unsigned MaxUsesToExplore) { assert(!isa<GlobalValue>(V) && "It doesn't make sense to ask whether a global is captured."); bool UseNewOBB = OBB == nullptr; if (!DT) - return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures); + return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures, + MaxUsesToExplore); if (UseNewOBB) OBB = new OrderedBasicBlock(I->getParent()); @@ -200,29 +202,25 @@ bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, // with StoreCaptures. CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB); - PointerMayBeCaptured(V, &CB); + PointerMayBeCaptured(V, &CB, MaxUsesToExplore); if (UseNewOBB) delete OBB; return CB.Captured; } -/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep -/// a cache. Then we can move the code from BasicAliasAnalysis into -/// that path, and remove this threshold. -static int const Threshold = 20; - -void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { +void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, + unsigned MaxUsesToExplore) { assert(V->getType()->isPointerTy() && "Capture is for pointers only!"); - SmallVector<const Use *, Threshold> Worklist; - SmallSet<const Use *, Threshold> Visited; + SmallVector<const Use *, DefaultMaxUsesToExplore> Worklist; + SmallSet<const Use *, DefaultMaxUsesToExplore> Visited; auto AddUses = [&](const Value *V) { - int Count = 0; + unsigned Count = 0; for (const Use &U : V->uses()) { // If there are lots of uses, conservatively say that the value // is captured to avoid taking too much compile time. - if (Count++ >= Threshold) + if (Count++ >= MaxUsesToExplore) return Tracker->tooManyUses(); if (!Visited.insert(&U).second) continue; @@ -241,11 +239,12 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { switch (I->getOpcode()) { case Instruction::Call: case Instruction::Invoke: { - CallSite CS(I); + auto *Call = cast<CallBase>(I); // Not captured if the callee is readonly, doesn't return a copy through // its return value and doesn't unwind (a readonly function can leak bits // by throwing an exception or not depending on the input value). - if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy()) + if (Call->onlyReadsMemory() && Call->doesNotThrow() && + Call->getType()->isVoidTy()) break; // The pointer is not captured if returned pointer is not captured. @@ -253,14 +252,14 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { // marked with nocapture do not capture. This means that places like // GetUnderlyingObject in ValueTracking or DecomposeGEPExpression // in BasicAA also need to know about this property. - if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(CS)) { - AddUses(I); + if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(Call)) { + AddUses(Call); break; } // Volatile operations effectively capture the memory location that they // load and store to. - if (auto *MI = dyn_cast<MemIntrinsic>(I)) + if (auto *MI = dyn_cast<MemIntrinsic>(Call)) if (MI->isVolatile()) if (Tracker->captured(U)) return; @@ -272,13 +271,14 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { // that loading a value from a pointer does not cause the pointer to be // captured, even though the loaded value might be the pointer itself // (think of self-referential objects). - CallSite::data_operand_iterator B = - CS.data_operands_begin(), E = CS.data_operands_end(); - for (CallSite::data_operand_iterator A = B; A != E; ++A) - if (A->get() == V && !CS.doesNotCapture(A - B)) + for (auto IdxOpPair : enumerate(Call->data_ops())) { + int Idx = IdxOpPair.index(); + Value *A = IdxOpPair.value(); + if (A == V && !Call->doesNotCapture(Idx)) // The parameter is not marked 'nocapture' - captured. if (Tracker->captured(U)) return; + } break; } case Instruction::Load: |