-bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
- assert(isa<PointerType>(V->getType()) && "Capture is for pointers only!");
- SmallVector<Use*, 16> Worklist;
- SmallSet<Use*, 16> Visited;
-
- for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end();
- UI != UE; ++UI) {
- Use *U = &UI.getUse();
- Visited.insert(U);
- Worklist.push_back(U);
+bool llvm::PointerMayBeCaptured(const Value *V,
+ bool ReturnCaptures, bool StoreCaptures) {
+ assert(!isa<GlobalValue>(V) &&
+ "It doesn't make sense to ask whether a global is captured.");
+
+ // TODO: If StoreCaptures is not true, we could do Fancy analysis
+ // to determine whether this store is not actually an escape point.
+ // In that case, BasicAliasAnalysis should be updated as well to
+ // take advantage of this.
+ (void)StoreCaptures;
+
+ SimpleCaptureTracker SCT(ReturnCaptures);
+ PointerMayBeCaptured(V, &SCT);
+ return SCT.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) {
+ assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
+ SmallVector<const Use *, Threshold> Worklist;
+ SmallSet<const Use *, Threshold> Visited;
+ int 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)
+ return Tracker->tooManyUses();
+
+ if (!Tracker->shouldExplore(&U)) continue;
+ Visited.insert(&U);
+ Worklist.push_back(&U);