|
14 | 14 | #define LLVM_ANALYSIS_CAPTURETRACKING_H |
15 | 15 |
|
16 | 16 | #include "llvm/ADT/DenseMap.h" |
| 17 | +#include "llvm/Support/ModRef.h" |
17 | 18 |
|
18 | 19 | namespace llvm { |
19 | 20 |
|
20 | 21 | class Value; |
21 | 22 | class Use; |
| 23 | + class CaptureInfo; |
22 | 24 | class DataLayout; |
23 | 25 | class Instruction; |
24 | 26 | class DominatorTree; |
@@ -94,31 +96,53 @@ namespace llvm { |
94 | 96 | /// U->getUser() is always an Instruction. |
95 | 97 | virtual bool shouldExplore(const Use *U); |
96 | 98 |
|
97 | | - /// captured - Information about the pointer was captured by the user of |
98 | | - /// use U. Return true to stop the traversal or false to continue looking |
99 | | - /// for more capturing instructions. |
100 | | - virtual bool captured(const Use *U) = 0; |
| 99 | + /// When returned from captures(), stop the traversal. |
| 100 | + static std::optional<CaptureComponents> stop() { return std::nullopt; } |
| 101 | + |
| 102 | + /// When returned from captures(), continue traversal, but do not follow |
| 103 | + /// the return value of this user, even if it has additional capture |
| 104 | + /// components. Should only be used if captures() has already taken the |
| 105 | + /// potential return caputres into account. |
| 106 | + static std::optional<CaptureComponents> continueIgnoringReturn() { |
| 107 | + return CaptureComponents::None; |
| 108 | + } |
| 109 | + |
| 110 | + /// When returned from captures(), continue traversal, and also follow |
| 111 | + /// the return value of this user if it has additional capture components |
| 112 | + /// (that is, capture components in Ret that are not part of Other). |
| 113 | + static std::optional<CaptureComponents> continueDefault(CaptureInfo CI) { |
| 114 | + CaptureComponents RetCC = CI.getRetComponents(); |
| 115 | + if (!capturesNothing(RetCC & ~CI.getOtherComponents())) |
| 116 | + return RetCC; |
| 117 | + return CaptureComponents::None; |
| 118 | + } |
| 119 | + |
| 120 | + /// Use U directly captures CI.getOtherComponents() and additionally |
| 121 | + /// CI.getRetComponents() through the return value of the user of U. |
| 122 | + /// |
| 123 | + /// Return std::nullopt to stop the traversal, or the CaptureComponents to |
| 124 | + /// follow via the return value, which must be a subset of |
| 125 | + /// CI.getRetComponents(). |
| 126 | + /// |
| 127 | + /// For convenience, prefer returning one of stop(), continueDefault(CI) or |
| 128 | + /// continueIgnoringReturn(). |
| 129 | + virtual std::optional<CaptureComponents> captured(const Use *U, |
| 130 | + CaptureInfo CI) = 0; |
101 | 131 |
|
102 | 132 | /// isDereferenceableOrNull - Overload to allow clients with additional |
103 | 133 | /// knowledge about pointer dereferenceability to provide it and thereby |
104 | 134 | /// avoid conservative responses when a pointer is compared to null. |
105 | 135 | virtual bool isDereferenceableOrNull(Value *O, const DataLayout &DL); |
106 | 136 | }; |
107 | 137 |
|
108 | | - /// Types of use capture kinds, see \p DetermineUseCaptureKind. |
109 | | - enum class UseCaptureKind { |
110 | | - NO_CAPTURE, |
111 | | - MAY_CAPTURE, |
112 | | - PASSTHROUGH, |
113 | | - }; |
114 | | - |
115 | 138 | /// Determine what kind of capture behaviour \p U may exhibit. |
116 | 139 | /// |
117 | | - /// A use can be no-capture, a use can potentially capture, or a use can be |
118 | | - /// passthrough such that the uses of the user or \p U should be inspected. |
| 140 | + /// The Other part of the returned CaptureInfo indicates which component of |
| 141 | + /// the pointer may be captured directly by the use. The Ret part indicates |
| 142 | + /// which components may be captured by following uses of the user of \p U. |
119 | 143 | /// The \p IsDereferenceableOrNull callback is used to rule out capturing for |
120 | 144 | /// certain comparisons. |
121 | | - UseCaptureKind |
| 145 | + CaptureInfo |
122 | 146 | DetermineUseCaptureKind(const Use &U, |
123 | 147 | llvm::function_ref<bool(Value *, const DataLayout &)> |
124 | 148 | IsDereferenceableOrNull); |
|
0 commit comments