Index: llvm/include/llvm/Analysis/CaptureTracking.h =================================================================== --- llvm/include/llvm/Analysis/CaptureTracking.h +++ llvm/include/llvm/Analysis/CaptureTracking.h @@ -21,14 +21,6 @@ class Instruction; class DominatorTree; - /// 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. - unsigned constexpr DefaultMaxUsesToExplore = 20; - /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can /// be expensive, so consider caching the results. The boolean ReturnCaptures @@ -38,10 +30,10 @@ /// automatically counts as capturing it or not. /// MaxUsesToExplore specifies how many uses should the analysis explore for /// one value before giving up due too "too many uses". - bool PointerMayBeCaptured(const Value *V, - bool ReturnCaptures, - bool StoreCaptures, - unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); + bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, + bool StoreCaptures, unsigned MaxUsesToExplore); + bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, + bool StoreCaptures); /// PointerMayBeCapturedBefore - Return true if this pointer value may be /// captured by the enclosing function (which is required to exist). If a @@ -57,8 +49,13 @@ /// one value before giving up due too "too many uses". bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - const DominatorTree *DT, bool IncludeI = false, - unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); + const DominatorTree *DT, + unsigned MaxUsesToExplore, + bool IncludeI = false); + bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, + bool StoreCaptures, const Instruction *I, + const DominatorTree *DT, + bool IncludeI = false); /// This callback is used in conjunction with PointerMayBeCaptured. In /// addition to the interface here, you'll need to provide your own getters @@ -94,7 +91,10 @@ /// MaxUsesToExplore specifies how many uses should the analysis explore for /// one value before giving up due too "too many uses". void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, - unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); + unsigned MaxUsesToExplore); + void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker); + + unsigned getDefaultMaxUsesToExploreForCaptureTracking(); } // end namespace llvm #endif Index: llvm/lib/Analysis/CaptureTracking.cpp =================================================================== --- llvm/lib/Analysis/CaptureTracking.cpp +++ llvm/lib/Analysis/CaptureTracking.cpp @@ -28,6 +28,21 @@ 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 +DefaultMaxUsesToExplore("ct-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; } @@ -160,6 +175,11 @@ }; } +bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, + bool StoreCaptures) { + return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures, + DefaultMaxUsesToExplore); +} /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can /// be expensive, so consider caching the results. The boolean ReturnCaptures @@ -184,6 +204,12 @@ return SCT.Captured; } +bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, + bool StoreCaptures, const Instruction *I, + const DominatorTree *DT, bool IncludeI) { + return PointerMayBeCapturedBefore(V, ReturnCaptures, StoreCaptures, I, DT, + DefaultMaxUsesToExplore, IncludeI); +} /// PointerMayBeCapturedBefore - Return true if this pointer value may be /// captured by the enclosing function (which is required to exist). If a /// DominatorTree is provided, only captures which happen before the given @@ -195,8 +221,9 @@ /// or not. bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - const DominatorTree *DT, bool IncludeI, - unsigned MaxUsesToExplore) { + const DominatorTree *DT, + unsigned MaxUsesToExplore, + bool IncludeI) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); @@ -212,11 +239,16 @@ return CB.Captured; } +void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { + PointerMayBeCaptured(V, Tracker, DefaultMaxUsesToExplore); +} + void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, unsigned MaxUsesToExplore) { assert(V->getType()->isPointerTy() && "Capture is for pointers only!"); - SmallVector Worklist; - SmallSet Visited; + SmallVector Worklist; + Worklist.reserve(MaxUsesToExplore); + SmallSet Visited; auto AddUses = [&](const Value *V) { unsigned Count = 0; Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -4170,7 +4170,8 @@ // defined in AACaptureUseTracker, that can look at in-flight abstract // attributes and directly updates the assumed state. SmallVector PotentialCopies; - unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore; + unsigned RemainingUsesToExplore = + getDefaultMaxUsesToExploreForCaptureTracking(); AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies, RemainingUsesToExplore); Index: llvm/unittests/Analysis/CaptureTrackingTest.cpp =================================================================== --- llvm/unittests/Analysis/CaptureTrackingTest.cpp +++ llvm/unittests/Analysis/CaptureTrackingTest.cpp @@ -64,10 +64,10 @@ Instruction *Ret = EntryBB->getTerminator(); ASSERT_TRUE(isa(Ret)); - ASSERT_FALSE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, false, - FalseMaxUsesLimit)); - ASSERT_TRUE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, false, - TrueMaxUsesLimit)); + ASSERT_FALSE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, + FalseMaxUsesLimit, false)); + ASSERT_TRUE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, + TrueMaxUsesLimit, false)); }; Test("test_few_uses", 6, 4);