@@ -44,16 +44,24 @@ static bool hasValueOwnership(SILValue value) {
44
44
value->getOwnershipKind () == OwnershipKind::Owned;
45
45
}
46
46
47
- // / Delete a chain of unused copies leading to \p v.
48
- static void deleteCopyChain (SILValue v, InstructionDeleter &deleter) {
49
- while (auto *copy = dyn_cast<CopyValueInst>(v)) {
50
- if (!onlyHaveDebugUses (copy))
47
+ static SingleValueInstruction *asCopyOrMove (SILValue v) {
48
+ if (auto *copy = dyn_cast<CopyValueInst>(v))
49
+ return copy;
50
+ if (auto *move = dyn_cast<MoveValueInst>(v))
51
+ return move;
52
+ return nullptr ;
53
+ }
54
+
55
+ // / Delete a chain of unused copies and moves leading to \p v.
56
+ static void deleteCopyAndMoveChain (SILValue v, InstructionDeleter &deleter) {
57
+ while (auto *inst = asCopyOrMove (v)) {
58
+ if (!onlyHaveDebugUses (inst))
51
59
break ;
52
60
53
- v = copy ->getOperand ();
54
- LLVM_DEBUG (llvm::dbgs () << " Deleting " << *copy );
55
- ++NumCopiesEliminated ;
56
- deleter.forceDelete (copy );
61
+ v = inst ->getOperand (CopyLikeInstruction::Src );
62
+ LLVM_DEBUG (llvm::dbgs () << " Deleting " << *inst );
63
+ ++NumCopiesAndMovesEliminated ;
64
+ deleter.forceDelete (inst );
57
65
}
58
66
}
59
67
@@ -182,11 +190,12 @@ bool CanonicalizeBorrowScope::computeBorrowLiveness() {
182
190
// / equivalent to the logic in visitBorrowScopeUses that recurses through
183
191
// / copies. The use-def and def-use logic must be consistent.
184
192
SILValue CanonicalizeBorrowScope::findDefInBorrowScope (SILValue value) {
185
- while (auto *copy = dyn_cast<CopyValueInst>(value)) {
186
- if (isPersistentCopy (copy))
193
+ while (auto *inst = asCopyOrMove (value)) {
194
+ auto *copy = dyn_cast<CopyValueInst>(inst);
195
+ if (copy && isPersistentCopy (copy))
187
196
return copy;
188
197
189
- value = copy ->getOperand ();
198
+ value = inst ->getOperand (0 );
190
199
}
191
200
return value;
192
201
}
@@ -224,21 +233,27 @@ bool CanonicalizeBorrowScope::visitBorrowScopeUses(SILValue innerValue,
224
233
// Gather the uses before updating any of them.
225
234
// 'value' may be deleted in this loop after rewriting its last use.
226
235
// 'use' may become invalid after processing its user.
236
+
227
237
SmallVector<Operand *, 4 > uses (value->getUses ());
228
- for (Operand *use : uses) {
238
+ for (auto *use : uses) {
229
239
auto *user = use->getUser ();
230
240
// Incidental uses, such as debug_value may be deleted before they can be
231
241
// processed. Their user will now be nullptr. This means that value
232
242
// is dead, so just bail.
233
243
if (!user)
234
244
break ;
235
245
236
- // Recurse through copies.
246
+ // Recurse through copies and moves .
237
247
if (auto *copy = dyn_cast<CopyValueInst>(user)) {
238
248
if (!isPersistentCopy (copy)) {
239
249
defUseWorklist.insert (copy);
240
250
continue ;
241
251
}
252
+ } else if (auto *move = dyn_cast<MoveValueInst>(user)) {
253
+ if (!move->isLexical () || innerValue->isLexical ()) {
254
+ defUseWorklist.insert (move);
255
+ continue ;
256
+ }
242
257
}
243
258
// Note: debug_value uses are handled like normal uses here. If they are
244
259
// inner uses, they remain. If they are outer uses, then they will be
@@ -433,7 +448,7 @@ class RewriteInnerBorrowUses {
433
448
// destroys are never needed within a borrow scope.
434
449
if (isa<DestroyValueInst>(user)) {
435
450
scope.getDeleter ().forceDelete (user);
436
- deleteCopyChain (value, scope.getDeleter ());
451
+ deleteCopyAndMoveChain (value, scope.getDeleter ());
437
452
return true ;
438
453
}
439
454
SILValue def = scope.findDefInBorrowScope (value);
@@ -447,12 +462,12 @@ class RewriteInnerBorrowUses {
447
462
use->set (def);
448
463
copyLiveUse (use, scope.getCallbacks ());
449
464
}
450
- deleteCopyChain (value, scope.getDeleter ());
465
+ deleteCopyAndMoveChain (value, scope.getDeleter ());
451
466
return true ;
452
467
}
453
468
// Non-consuming use.
454
469
use->set (def);
455
- deleteCopyChain (value, scope.getDeleter ());
470
+ deleteCopyAndMoveChain (value, scope.getDeleter ());
456
471
return true ;
457
472
}
458
473
@@ -474,7 +489,7 @@ class RewriteInnerBorrowUses {
474
489
use->set (scope.findDefInBorrowScope (value));
475
490
ForwardingOperand (use).setForwardingOwnershipKind (
476
491
OwnershipKind::Guaranteed);
477
- deleteCopyChain (value, scope.getDeleter ());
492
+ deleteCopyAndMoveChain (value, scope.getDeleter ());
478
493
return true ;
479
494
}
480
495
};
@@ -593,7 +608,7 @@ class RewriteOuterBorrowUses {
593
608
ForwardingOperand (use).setForwardingOwnershipKind (
594
609
OwnershipKind::Guaranteed);
595
610
}
596
- deleteCopyChain (innerValue, scope.getDeleter ());
611
+ deleteCopyAndMoveChain (innerValue, scope.getDeleter ());
597
612
return true ;
598
613
}
599
614
@@ -644,7 +659,7 @@ class RewriteOuterBorrowUses {
644
659
645
660
use->set (outerValue);
646
661
647
- deleteCopyChain (innerValue, scope.getDeleter ());
662
+ deleteCopyAndMoveChain (innerValue, scope.getDeleter ());
648
663
649
664
recordOuterUse (use);
650
665
};
0 commit comments