@@ -185,6 +185,9 @@ struct MoveOnlyObjectCheckerPImpl {
185
185
186
186
bool
187
187
checkForSameInstMultipleUseErrors (MarkUnresolvedNonCopyableValueInst *base);
188
+
189
+ bool eraseMarkWithCopiedOperand (
190
+ MarkUnresolvedNonCopyableValueInst *markedInst);
188
191
};
189
192
190
193
} // namespace
@@ -463,9 +466,6 @@ void MoveOnlyObjectCheckerPImpl::check(
463
466
// MarkUnresolvedNonCopyableValueInst in Raw SIL. This ensures we do not
464
467
// miss any.
465
468
//
466
- // NOTE: destroys is a separate array that we use to avoid iterator
467
- // invalidation when cleaning up destroy_value of guaranteed checked values.
468
- SmallVector<DestroyValueInst *, 8 > destroys;
469
469
while (!moveIntroducersToProcess.empty ()) {
470
470
auto *markedInst = moveIntroducersToProcess.pop_back_val ();
471
471
@@ -475,80 +475,98 @@ void MoveOnlyObjectCheckerPImpl::check(
475
475
if (!diagnosticEmitter.emittedDiagnosticForValue (markedInst)) {
476
476
if (markedInst->getCheckKind () ==
477
477
MarkUnresolvedNonCopyableValueInst::CheckKind::NoConsumeOrAssign) {
478
- if (auto *cvi = dyn_cast<CopyValueInst>(markedInst->getOperand ())) {
479
- auto replacement = cvi->getOperand ();
480
- auto orig = replacement;
481
- if (auto *copyToMoveOnly =
482
- dyn_cast<CopyableToMoveOnlyWrapperValueInst>(orig)) {
483
- orig = copyToMoveOnly->getOperand ();
484
- }
485
-
486
- // TODO: Instead of pattern matching specific code generation patterns,
487
- // we should be able to eliminate any `copy_value` whose canonical
488
- // lifetime fits within the borrow scope of the borrowed value being
489
- // copied from.
490
-
491
- // Handle:
492
- //
493
- // bb(%arg : @guaranteed $Type):
494
- // %copy = copy_value %arg
495
- // %mark = mark_unresolved_non_copyable_value [no_consume_or_assign] %copy
496
- if (auto *arg = dyn_cast<SILArgument>(orig)) {
497
- if (arg->getOwnershipKind () == OwnershipKind::Guaranteed) {
498
- for (auto *use : markedInst->getConsumingUses ()) {
499
- destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
500
- }
501
- while (!destroys.empty ())
502
- destroys.pop_back_val ()->eraseFromParent ();
503
- markedInst->replaceAllUsesWith (replacement);
504
- markedInst->eraseFromParent ();
505
- cvi->eraseFromParent ();
506
- continue ;
507
- }
508
- }
509
-
510
- // Handle:
511
- //
512
- // %1 = load_borrow %0
513
- // %2 = copy_value %1
514
- // %3 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
515
- if (isa<LoadBorrowInst>(orig)) {
516
- for (auto *use : markedInst->getConsumingUses ()) {
517
- destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
518
- }
519
- while (!destroys.empty ())
520
- destroys.pop_back_val ()->eraseFromParent ();
521
- markedInst->replaceAllUsesWith (replacement);
522
- markedInst->eraseFromParent ();
523
- cvi->eraseFromParent ();
524
- continue ;
525
- }
526
-
527
- // Handle:
528
- // (%yield, ..., %handle) = begin_apply
529
- // %copy = copy_value %yield
530
- // %mark = mark_unresolved_noncopyable_value [no_consume_or_assign] %copy
531
- if (isa_and_nonnull<BeginApplyInst>(orig->getDefiningInstruction ())) {
532
- if (orig->getOwnershipKind () == OwnershipKind::Guaranteed) {
533
- for (auto *use : markedInst->getConsumingUses ()) {
534
- destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
535
- }
536
- while (!destroys.empty ())
537
- destroys.pop_back_val ()->eraseFromParent ();
538
- markedInst->replaceAllUsesWith (replacement);
539
- markedInst->eraseFromParent ();
540
- cvi->eraseFromParent ();
541
- continue ;
542
- }
543
- }
478
+ if (eraseMarkWithCopiedOperand (markedInst)) {
479
+ changed = true ;
480
+ continue ;
544
481
}
545
482
}
483
+ markedInst->replaceAllUsesWith (markedInst->getOperand ());
484
+ markedInst->eraseFromParent ();
485
+ changed = true ;
486
+ }
487
+ }
488
+ }
489
+
490
+ // / Erase a copy_value operand of MarkUnresolvedNonCopyableValueInst.
491
+ bool MoveOnlyObjectCheckerPImpl::eraseMarkWithCopiedOperand (
492
+ MarkUnresolvedNonCopyableValueInst *markedInst)
493
+ {
494
+ auto *cvi = dyn_cast<CopyValueInst>(markedInst->getOperand ());
495
+ if (!cvi)
496
+ return false ;
497
+
498
+ auto replacement = cvi->getOperand ();
499
+ auto orig = replacement;
500
+ if (auto *copyToMoveOnly =
501
+ dyn_cast<CopyableToMoveOnlyWrapperValueInst>(orig)) {
502
+ orig = copyToMoveOnly->getOperand ();
503
+ }
504
+
505
+ // TODO: Instead of pattern matching specific code generation patterns,
506
+ // we should be able to eliminate any `copy_value` whose canonical
507
+ // lifetime fits within the borrow scope of the borrowed value being
508
+ // copied from.
509
+
510
+ // NOTE: destroys is a separate array that we use to avoid iterator
511
+ // invalidation when cleaning up destroy_value of guaranteed checked values.
512
+ SmallVector<DestroyValueInst *, 8 > destroys;
513
+
514
+ // Handle:
515
+ //
516
+ // bb(%arg : @guaranteed $Type):
517
+ // %copy = copy_value %arg
518
+ // %mark = mark_unresolved_non_copyable_value [no_consume_or_assign]
519
+ // %copy
520
+ if (auto *arg = dyn_cast<SILArgument>(orig)) {
521
+ if (arg->getOwnershipKind () == OwnershipKind::Guaranteed) {
522
+ for (auto *use : markedInst->getConsumingUses ()) {
523
+ destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
524
+ }
525
+ while (!destroys.empty ())
526
+ destroys.pop_back_val ()->eraseFromParent ();
527
+ markedInst->replaceAllUsesWith (replacement);
528
+ markedInst->eraseFromParent ();
529
+ cvi->eraseFromParent ();
530
+ return true ;
546
531
}
532
+ }
547
533
548
- markedInst->replaceAllUsesWith (markedInst->getOperand ());
534
+ // Handle:
535
+ //
536
+ // %1 = load_borrow %0
537
+ // %2 = copy_value %1
538
+ // %3 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
539
+ if (isa<LoadBorrowInst>(orig)) {
540
+ for (auto *use : markedInst->getConsumingUses ()) {
541
+ destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
542
+ }
543
+ while (!destroys.empty ())
544
+ destroys.pop_back_val ()->eraseFromParent ();
545
+ markedInst->replaceAllUsesWith (replacement);
549
546
markedInst->eraseFromParent ();
550
- changed = true ;
547
+ cvi->eraseFromParent ();
548
+ return true ;
549
+ }
550
+
551
+ // Handle:
552
+ // (%yield, ..., %handle) = begin_apply
553
+ // %copy = copy_value %yield
554
+ // %mark = mark_unresolved_noncopyable_value [no_consume_or_assign]
555
+ // %copy
556
+ if (isa_and_nonnull<BeginApplyInst>(orig->getDefiningInstruction ())) {
557
+ if (orig->getOwnershipKind () == OwnershipKind::Guaranteed) {
558
+ for (auto *use : markedInst->getConsumingUses ()) {
559
+ destroys.push_back (cast<DestroyValueInst>(use->getUser ()));
560
+ }
561
+ while (!destroys.empty ())
562
+ destroys.pop_back_val ()->eraseFromParent ();
563
+ markedInst->replaceAllUsesWith (replacement);
564
+ markedInst->eraseFromParent ();
565
+ cvi->eraseFromParent ();
566
+ return true ;
567
+ }
551
568
}
569
+ return false ;
552
570
}
553
571
554
572
// ===----------------------------------------------------------------------===//
0 commit comments