diff options
Diffstat (limited to 'llvm/lib/Analysis/CaptureTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp index 20e2f06540a38..8b101e3b2cc47 100644 --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -20,15 +20,30 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CFG.h" -#include "llvm/Analysis/OrderedBasicBlock.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; +/// The default value for MaxUsesToExplore argument. It's relatively small to +/// keep the cost of analysis reasonable for clients like BasicAliasAnalysis, +/// where the results can't be cached. +/// TODO: we should probably introduce a caching CaptureTracking analysis and +/// use it where possible. The caching version can use much higher limit or +/// don't have this cap at all. +static cl::opt<unsigned> +DefaultMaxUsesToExplore("capture-tracking-max-uses-to-explore", cl::Hidden, + cl::desc("Maximal number of uses to explore."), + cl::init(20)); + +unsigned llvm::getDefaultMaxUsesToExploreForCaptureTracking() { + return DefaultMaxUsesToExplore; +} + CaptureTracker::~CaptureTracker() {} bool CaptureTracker::shouldExplore(const Use *U) { return true; } @@ -76,8 +91,8 @@ namespace { struct CapturesBefore : public CaptureTracker { CapturesBefore(bool ReturnCaptures, const Instruction *I, const DominatorTree *DT, - bool IncludeI, OrderedBasicBlock *IC) - : OrderedBB(IC), BeforeHere(I), DT(DT), + bool IncludeI) + : BeforeHere(I), DT(DT), ReturnCaptures(ReturnCaptures), IncludeI(IncludeI), Captured(false) {} void tooManyUses() override { Captured = true; } @@ -90,9 +105,7 @@ namespace { return true; // Compute the case where both instructions are inside the same basic - // block. Since instructions in the same BB as BeforeHere are numbered in - // 'OrderedBB', avoid using 'dominates' and 'isPotentiallyReachable' - // which are very expensive for large basic blocks. + // block. if (BB == BeforeHere->getParent()) { // 'I' dominates 'BeforeHere' => not safe to prune. // @@ -102,7 +115,7 @@ namespace { // UseBB == BB, avoid pruning. if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I == BeforeHere) return false; - if (!OrderedBB->dominates(BeforeHere, I)) + if (!BeforeHere->comesBefore(I)) return false; // 'BeforeHere' comes before 'I', it's safe to prune if we also @@ -153,7 +166,6 @@ namespace { return true; } - OrderedBasicBlock *OrderedBB; const Instruction *BeforeHere; const DominatorTree *DT; @@ -196,39 +208,35 @@ bool llvm::PointerMayBeCaptured(const Value *V, /// returning the value (or part of it) from the function counts as capturing /// it or not. The boolean StoreCaptures specified whether storing the value /// (or part of it) into memory anywhere automatically counts as capturing it -/// or not. A ordered basic block \p OBB can be used in order to speed up -/// queries about relative order among instructions in the same basic block. +/// or not. bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, const DominatorTree *DT, bool IncludeI, - 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, MaxUsesToExplore); - if (UseNewOBB) - OBB = new OrderedBasicBlock(I->getParent()); // TODO: See comment in PointerMayBeCaptured regarding what could be done // with StoreCaptures. - CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB); + CapturesBefore CB(ReturnCaptures, I, DT, IncludeI); PointerMayBeCaptured(V, &CB, MaxUsesToExplore); - - if (UseNewOBB) - delete OBB; return CB.Captured; } void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, unsigned MaxUsesToExplore) { assert(V->getType()->isPointerTy() && "Capture is for pointers only!"); - SmallVector<const Use *, DefaultMaxUsesToExplore> Worklist; - SmallSet<const Use *, DefaultMaxUsesToExplore> Visited; + if (MaxUsesToExplore == 0) + MaxUsesToExplore = DefaultMaxUsesToExplore; + + SmallVector<const Use *, 20> Worklist; + Worklist.reserve(getDefaultMaxUsesToExploreForCaptureTracking()); + SmallSet<const Use *, 20> Visited; auto AddUses = [&](const Value *V) { unsigned Count = 0; |