summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/CaptureTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/CaptureTracking.cpp')
-rw-r--r--llvm/lib/Analysis/CaptureTracking.cpp48
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;