Skip to content

Commit eba2365

Browse files
committedNov 29, 2018
Introduce MaxUsesToExplore argument to capture tracking
Currently CaptureTracker gives up if it encounters a value with more than 20 uses. The motivation for this cap is to keep it relatively cheap for BasicAliasAnalysis use case, where the results can't be cached. Although, other clients of CaptureTracker might be ok with higher cost. This patch introduces an argument for PointerMayBeCaptured functions to specify the max number of uses to explore. The motivation for this change is a downstream user of CaptureTracker, but I believe upstream clients of CaptureTracker might also benefit from more fine grained cap. Reviewed By: hfinkel Differential Revision: https://reviews.llvm.org/D55042 llvm-svn: 347910
1 parent 0f90191 commit eba2365

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed
 

Diff for: ‎llvm/include/llvm/Analysis/CaptureTracking.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,27 @@ namespace llvm {
2222
class DominatorTree;
2323
class OrderedBasicBlock;
2424

25+
/// The default value for MaxUsesToExplore argument. It's relatively small to
26+
/// keep the cost of analysis reasonable for clients like BasicAliasAnalysis,
27+
/// where the results can't be cached.
28+
/// TODO: we should probably introduce a caching CaptureTracking analysis and
29+
/// use it where possible. The caching version can use much higher limit or
30+
/// don't have this cap at all.
31+
unsigned constexpr DefaultMaxUsesToExplore = 20;
32+
2533
/// PointerMayBeCaptured - Return true if this pointer value may be captured
2634
/// by the enclosing function (which is required to exist). This routine can
2735
/// be expensive, so consider caching the results. The boolean ReturnCaptures
2836
/// specifies whether returning the value (or part of it) from the function
2937
/// counts as capturing it or not. The boolean StoreCaptures specified
3038
/// whether storing the value (or part of it) into memory anywhere
3139
/// automatically counts as capturing it or not.
40+
/// MaxUsesToExplore specifies how many uses should the analysis explore for
41+
/// one value before giving up due too "too many uses".
3242
bool PointerMayBeCaptured(const Value *V,
3343
bool ReturnCaptures,
34-
bool StoreCaptures);
44+
bool StoreCaptures,
45+
unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
3546

3647
/// PointerMayBeCapturedBefore - Return true if this pointer value may be
3748
/// captured by the enclosing function (which is required to exist). If a
@@ -44,10 +55,13 @@ namespace llvm {
4455
/// or not. Captures by the provided instruction are considered if the
4556
/// final parameter is true. An ordered basic block in \p OBB could be used
4657
/// to speed up capture-tracker queries.
58+
/// MaxUsesToExplore specifies how many uses should the analysis explore for
59+
/// one value before giving up due too "too many uses".
4760
bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
4861
bool StoreCaptures, const Instruction *I,
4962
const DominatorTree *DT, bool IncludeI = false,
50-
OrderedBasicBlock *OBB = nullptr);
63+
OrderedBasicBlock *OBB = nullptr,
64+
unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
5165

5266
/// This callback is used in conjunction with PointerMayBeCaptured. In
5367
/// addition to the interface here, you'll need to provide your own getters
@@ -75,7 +89,10 @@ namespace llvm {
7589
/// PointerMayBeCaptured - Visit the value and the values derived from it and
7690
/// find values which appear to be capturing the pointer value. This feeds
7791
/// results into and is controlled by the CaptureTracker object.
78-
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker);
92+
/// MaxUsesToExplore specifies how many uses should the analysis explore for
93+
/// one value before giving up due too "too many uses".
94+
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
95+
unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
7996
} // end namespace llvm
8097

8198
#endif

Diff for: ‎llvm/lib/Analysis/CaptureTracking.cpp

+9-11
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ namespace {
158158
/// storing the value (or part of it) into memory anywhere automatically
159159
/// counts as capturing it or not.
160160
bool llvm::PointerMayBeCaptured(const Value *V,
161-
bool ReturnCaptures, bool StoreCaptures) {
161+
bool ReturnCaptures, bool StoreCaptures,
162+
unsigned MaxUsesToExplore) {
162163
assert(!isa<GlobalValue>(V) &&
163164
"It doesn't make sense to ask whether a global is captured.");
164165

@@ -186,7 +187,8 @@ bool llvm::PointerMayBeCaptured(const Value *V,
186187
bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
187188
bool StoreCaptures, const Instruction *I,
188189
const DominatorTree *DT, bool IncludeI,
189-
OrderedBasicBlock *OBB) {
190+
OrderedBasicBlock *OBB,
191+
unsigned MaxUsesToExplore) {
190192
assert(!isa<GlobalValue>(V) &&
191193
"It doesn't make sense to ask whether a global is captured.");
192194
bool UseNewOBB = OBB == nullptr;
@@ -207,22 +209,18 @@ bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
207209
return CB.Captured;
208210
}
209211

210-
/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep
211-
/// a cache. Then we can move the code from BasicAliasAnalysis into
212-
/// that path, and remove this threshold.
213-
static unsigned const Threshold = 20;
214-
215-
void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) {
212+
void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
213+
unsigned MaxUsesToExplore) {
216214
assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
217-
SmallVector<const Use *, Threshold> Worklist;
218-
SmallSet<const Use *, Threshold> Visited;
215+
SmallVector<const Use *, DefaultMaxUsesToExplore> Worklist;
216+
SmallSet<const Use *, DefaultMaxUsesToExplore> Visited;
219217

220218
auto AddUses = [&](const Value *V) {
221219
unsigned Count = 0;
222220
for (const Use &U : V->uses()) {
223221
// If there are lots of uses, conservatively say that the value
224222
// is captured to avoid taking too much compile time.
225-
if (Count++ >= Threshold)
223+
if (Count++ >= MaxUsesToExplore)
226224
return Tracker->tooManyUses();
227225
if (!Visited.insert(&U).second)
228226
continue;

0 commit comments

Comments
 (0)
Please sign in to comment.