|
102 | 102 |
|
103 | 103 | namespace swift {
|
104 | 104 |
|
| 105 | +/// Convert this struct_extract into a copy+destructure. Return the destructured |
| 106 | +/// result or invalid SILValue. The caller must delete the extract and its |
| 107 | +/// now-dead copy use. |
| 108 | +/// |
| 109 | +// If a copied-def is a struct-extract, attempt a destructure conversion |
| 110 | +// %extract = struct_extract %... : $TypeWithSingleOwnershipValue |
| 111 | +// %copy = copy_value %extract : $OwnershipValue |
| 112 | +// To: |
| 113 | +// %copy = copy_value %extract : $TypeWithSingleOwnershipValue |
| 114 | +// (%extracted,...) = destructure %copy : $TypeWithSingleOwnershipValue |
| 115 | +SILValue convertExtractToDestructure(StructExtractInst *extract); |
| 116 | + |
105 | 117 | /// Information about consumes on the extended-lifetime boundary. Consuming uses
|
106 | 118 | /// within the lifetime are not included--they will consume a copy after
|
107 | 119 | /// rewriting. For borrowed def values, the consumes do not include the end of
|
@@ -175,6 +187,50 @@ class CanonicalOSSAConsumeInfo {
|
175 | 187 | SWIFT_ASSERT_ONLY_DECL(void dump() const LLVM_ATTRIBUTE_USED);
|
176 | 188 | };
|
177 | 189 |
|
| 190 | +// Worklist of pointer-like things that have an invalid default value. Avoid |
| 191 | +// revisiting nodes--suitable for DAGs, but pops finished nodes without |
| 192 | +// preserving them in the vector. |
| 193 | +// |
| 194 | +// The primary API has two methods: intialize() and pop(). Others are provided |
| 195 | +// for flexibility. |
| 196 | +// |
| 197 | +// TODO: make this a better utility. |
| 198 | +template <typename T, unsigned SmallSize> struct PtrWorklist { |
| 199 | + SmallPtrSet<T, SmallSize> ptrVisited; |
| 200 | + SmallVector<T, SmallSize> ptrVector; |
| 201 | + |
| 202 | + PtrWorklist() = default; |
| 203 | + |
| 204 | + PtrWorklist(const PtrWorklist &) = delete; |
| 205 | + |
| 206 | + void initialize(T t) { |
| 207 | + clear(); |
| 208 | + insert(t); |
| 209 | + } |
| 210 | + |
| 211 | + template <typename R> void initializeRange(R &&range) { |
| 212 | + clear(); |
| 213 | + ptrVisited.insert(range.begin(), range.end()); |
| 214 | + ptrVector.append(range.begin(), range.end()); |
| 215 | + } |
| 216 | + |
| 217 | + T pop() { return empty() ? T() : ptrVector.pop_back_val(); } |
| 218 | + |
| 219 | + bool empty() const { return ptrVector.empty(); } |
| 220 | + |
| 221 | + unsigned size() const { return ptrVector.size(); } |
| 222 | + |
| 223 | + void clear() { |
| 224 | + ptrVector.clear(); |
| 225 | + ptrVisited.clear(); |
| 226 | + } |
| 227 | + |
| 228 | + void insert(T t) { |
| 229 | + if (ptrVisited.insert(t).second) |
| 230 | + ptrVector.push_back(t); |
| 231 | + } |
| 232 | +}; |
| 233 | + |
178 | 234 | /// Canonicalize OSSA lifetimes.
|
179 | 235 | ///
|
180 | 236 | /// Allows the allocation of analysis state to be reused across calls to
|
@@ -221,11 +277,11 @@ class CanonicalizeOSSALifetime {
|
221 | 277 | /// outisde the pruned liveness at the time it is discovered.
|
222 | 278 | llvm::SmallPtrSet<DebugValueInst *, 8> debugValues;
|
223 | 279 |
|
224 |
| - /// Reuse a general worklist for def-use traversal. |
225 |
| - SmallSetVector<SILValue, 8> defUseWorklist; |
| 280 | + /// Reuse a general visited set for def-use traversal. |
| 281 | + PtrWorklist<SILValue, 8> defUseWorklist; |
226 | 282 |
|
227 | 283 | /// Reuse a general worklist for CFG traversal.
|
228 |
| - SmallSetVector<SILBasicBlock *, 8> blockWorklist; |
| 284 | + PtrWorklist<SILBasicBlock *, 8> blockWorklist; |
229 | 285 |
|
230 | 286 | /// Pruned liveness for the extended live range including copies. For this
|
231 | 287 | /// purpose, only consuming instructions are considered "lifetime
|
@@ -298,6 +354,15 @@ class CanonicalizeOSSALifetime {
|
298 | 354 |
|
299 | 355 | bool consolidateBorrowScope();
|
300 | 356 |
|
| 357 | + bool findBorrowScopeUses(llvm::SmallPtrSetImpl<SILInstruction *> &useInsts); |
| 358 | + |
| 359 | + void filterOuterBorrowUseInsts( |
| 360 | + llvm::SmallPtrSetImpl<SILInstruction *> &outerUseInsts); |
| 361 | + |
| 362 | + void rewriteOuterBorrowUsesAndFindConsumes( |
| 363 | + SILValue incomingValue, |
| 364 | + llvm::SmallPtrSetImpl<SILInstruction *> &outerUseInsts); |
| 365 | + |
301 | 366 | bool computeCanonicalLiveness();
|
302 | 367 |
|
303 | 368 | bool endsAccessOverlappingPrunedBoundary(SILInstruction *inst);
|
|
0 commit comments