@@ -100,6 +100,106 @@ insertOwnedBaseValueAlongBranchEdge(BranchInst *bi, SILValue innerCopy,
100
100
return phiArg;
101
101
}
102
102
103
+ // ===----------------------------------------------------------------------===//
104
+ // Ownership RAUW Helper Functions
105
+ // ===----------------------------------------------------------------------===//
106
+
107
+ // Determine whether it is valid to replace \p oldValue with \p newValue by
108
+ // directly checking ownership requirements. This does not determine whether the
109
+ // scope of the newValue can be fully extended.
110
+ bool OwnershipRAUWHelper::hasValidRAUWOwnership (SILValue oldValue,
111
+ SILValue newValue) {
112
+ auto newOwnershipKind = newValue.getOwnershipKind ();
113
+
114
+ // If our new kind is ValueOwnershipKind::None, then we are fine. We
115
+ // trivially support that. This check also ensures that we can always
116
+ // replace any value with a ValueOwnershipKind::None value.
117
+ if (newOwnershipKind == OwnershipKind::None)
118
+ return true ;
119
+
120
+ // If our old ownership kind is ValueOwnershipKind::None and our new kind is
121
+ // not, we may need to do more work that has not been implemented yet. So
122
+ // bail.
123
+ //
124
+ // Due to our requirement that types line up, this can only occur given a
125
+ // non-trivial typed value with None ownership. This can only happen when
126
+ // oldValue is a trivial payloaded or no-payload non-trivially typed
127
+ // enum. That doesn't occur that often so we just bail on it today until we
128
+ // implement this functionality.
129
+ if (oldValue.getOwnershipKind () == OwnershipKind::None)
130
+ return false ;
131
+
132
+ // First check if oldValue is SILUndef. If it is, then we know that:
133
+ //
134
+ // 1. SILUndef (and thus oldValue) must have OwnershipKind::None.
135
+ // 2. newValue is not OwnershipKind::None due to our check above.
136
+ //
137
+ // Thus we know that we would be replacing a value with OwnershipKind::None
138
+ // with a value with non-None ownership. This is a case we don't support, so
139
+ // we can bail now.
140
+ if (isa<SILUndef>(oldValue))
141
+ return false ;
142
+
143
+ // Ok, we now know that we do not have SILUndef implying that we must be able
144
+ // to get a module from our value since we must have an argument or an
145
+ // instruction.
146
+ auto *m = oldValue->getModule ();
147
+ assert (m);
148
+
149
+ // If we are in Raw SIL, just bail at this point. We do not support
150
+ // ownership fixups.
151
+ if (m->getStage () == SILStage::Raw)
152
+ return false ;
153
+
154
+ return true ;
155
+ }
156
+
157
+ // Determine whether it is valid to replace \p oldValue with \p newValue and
158
+ // extend the lifetime of \p oldValue to cover the new uses.
159
+ //
160
+ // This updates the OwnershipFixupContext, populating transitiveBorrowedUses and
161
+ // recursiveReborrows.
162
+ static bool canFixUpOwnershipForRAUW (SILValue oldValue, SILValue newValue,
163
+ OwnershipFixupContext &context) {
164
+ if (!OwnershipRAUWHelper::hasValidRAUWOwnership (oldValue, newValue))
165
+ return false ;
166
+
167
+ if (oldValue.getOwnershipKind () != OwnershipKind::Guaranteed)
168
+ return true ;
169
+
170
+ // Check that the old lifetime can be extended and record the necessary
171
+ // book-keeping in the OwnershipFixupContext.
172
+ context.clear ();
173
+
174
+ // Note: The following code is the same logic as
175
+ // findExtendedTransitiveGuaranteedUses(), but it handles the reborrows
176
+ // itself to maintain book-keeping. This is intended to be moved into a
177
+ // different utility in a follow-up commit.
178
+ SmallSetVector<SILValue, 4 > reborrows;
179
+ auto visitReborrow = [&](Operand *endScope) {
180
+ auto borrowingOper = BorrowingOperand (endScope);
181
+ assert (borrowingOper.isReborrow ());
182
+ // TODO: if non-phi reborrows ever exist, handle them using a separate
183
+ // SILValue list since we don't want to refer directly to phi SILValues.
184
+ reborrows.insert (borrowingOper.getBorrowIntroducingUserResult ().value );
185
+ context.recursiveReborrows .push_back (endScope);
186
+ };
187
+ if (!findTransitiveGuaranteedUses (oldValue, context.transitiveBorrowedUses ,
188
+ visitReborrow))
189
+ return false ;
190
+
191
+ for (unsigned idx = 0 ; idx < reborrows.size (); ++idx) {
192
+ bool result =
193
+ findTransitiveGuaranteedUses (reborrows[idx],
194
+ context.transitiveBorrowedUses ,
195
+ visitReborrow);
196
+ // It is impossible to find a Pointer escape while traversing reborrows.
197
+ assert (result && " visiting reborrows always succeeds" );
198
+ (void )result;
199
+ }
200
+ return true ;
201
+ }
202
+
103
203
// ===----------------------------------------------------------------------===//
104
204
// BorrowedLifetimeExtender
105
205
// ===----------------------------------------------------------------------===//
@@ -332,106 +432,6 @@ extendOverBorrowScopeAndConsume(SILValue ownedValue) {
332
432
}
333
433
}
334
434
335
- // ===----------------------------------------------------------------------===//
336
- // Ownership RAUW Helper Functions
337
- // ===----------------------------------------------------------------------===//
338
-
339
- // Determine whether it is valid to replace \p oldValue with \p newValue by
340
- // directly checking ownership requirements. This does not determine whether the
341
- // scope of the newValue can be fully extended.
342
- bool OwnershipRAUWHelper::hasValidRAUWOwnership (SILValue oldValue,
343
- SILValue newValue) {
344
- auto newOwnershipKind = newValue.getOwnershipKind ();
345
-
346
- // If our new kind is ValueOwnershipKind::None, then we are fine. We
347
- // trivially support that. This check also ensures that we can always
348
- // replace any value with a ValueOwnershipKind::None value.
349
- if (newOwnershipKind == OwnershipKind::None)
350
- return true ;
351
-
352
- // If our old ownership kind is ValueOwnershipKind::None and our new kind is
353
- // not, we may need to do more work that has not been implemented yet. So
354
- // bail.
355
- //
356
- // Due to our requirement that types line up, this can only occur given a
357
- // non-trivial typed value with None ownership. This can only happen when
358
- // oldValue is a trivial payloaded or no-payload non-trivially typed
359
- // enum. That doesn't occur that often so we just bail on it today until we
360
- // implement this functionality.
361
- if (oldValue.getOwnershipKind () == OwnershipKind::None)
362
- return false ;
363
-
364
- // First check if oldValue is SILUndef. If it is, then we know that:
365
- //
366
- // 1. SILUndef (and thus oldValue) must have OwnershipKind::None.
367
- // 2. newValue is not OwnershipKind::None due to our check above.
368
- //
369
- // Thus we know that we would be replacing a value with OwnershipKind::None
370
- // with a value with non-None ownership. This is a case we don't support, so
371
- // we can bail now.
372
- if (isa<SILUndef>(oldValue))
373
- return false ;
374
-
375
- // Ok, we now know that we do not have SILUndef implying that we must be able
376
- // to get a module from our value since we must have an argument or an
377
- // instruction.
378
- auto *m = oldValue->getModule ();
379
- assert (m);
380
-
381
- // If we are in Raw SIL, just bail at this point. We do not support
382
- // ownership fixups.
383
- if (m->getStage () == SILStage::Raw)
384
- return false ;
385
-
386
- return true ;
387
- }
388
-
389
- // Determine whether it is valid to replace \p oldValue with \p newValue and
390
- // extend the lifetime of \p oldValue to cover the new uses.
391
- //
392
- // This updates the OwnershipFixupContext, populating transitiveBorrowedUses and
393
- // recursiveReborrows.
394
- static bool canFixUpOwnershipForRAUW (SILValue oldValue, SILValue newValue,
395
- OwnershipFixupContext &context) {
396
- if (!OwnershipRAUWHelper::hasValidRAUWOwnership (oldValue, newValue))
397
- return false ;
398
-
399
- if (oldValue.getOwnershipKind () != OwnershipKind::Guaranteed)
400
- return true ;
401
-
402
- // Check that the old lifetime can be extended and record the necessary
403
- // book-keeping in the OwnershipFixupContext.
404
- context.clear ();
405
-
406
- // Note: The following code is the same logic as
407
- // findExtendedTransitiveGuaranteedUses(), but it handles the reborrows
408
- // itself to maintain book-keeping. This is intended to be moved into a
409
- // different utility in a follow-up commit.
410
- SmallSetVector<SILValue, 4 > reborrows;
411
- auto visitReborrow = [&](Operand *endScope) {
412
- auto borrowingOper = BorrowingOperand (endScope);
413
- assert (borrowingOper.isReborrow ());
414
- // TODO: if non-phi reborrows ever exist, handle them using a separate
415
- // SILValue list since we don't want to refer directly to phi SILValues.
416
- reborrows.insert (borrowingOper.getBorrowIntroducingUserResult ().value );
417
- context.recursiveReborrows .push_back (endScope);
418
- };
419
- if (!findTransitiveGuaranteedUses (oldValue, context.transitiveBorrowedUses ,
420
- visitReborrow))
421
- return false ;
422
-
423
- for (unsigned idx = 0 ; idx < reborrows.size (); ++idx) {
424
- bool result =
425
- findTransitiveGuaranteedUses (reborrows[idx],
426
- context.transitiveBorrowedUses ,
427
- visitReborrow);
428
- // It is impossible to find a Pointer escape while traversing reborrows.
429
- assert (result && " visiting reborrows always succeeds" );
430
- (void )result;
431
- }
432
- return true ;
433
- }
434
-
435
435
// ===----------------------------------------------------------------------===//
436
436
// Ownership Lifetime Extender
437
437
// ===----------------------------------------------------------------------===//
0 commit comments