@@ -608,14 +608,19 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
608
608
// value, we need to ensure that the guaranteed value is live at all use
609
609
// points of the unowned value. If so, just replace and continue.
610
610
//
611
- // TODO: Implement this.
611
+ // TODO: Implement this for more interesting cases.
612
+ if (isa<SILFunctionArgument>(newValue))
613
+ return replaceAllUsesAndErase (oldValue, newValue, callbacks);
612
614
613
615
// Otherwise, we need to lifetime extend the borrow over all of the use
614
- // points. To do so, we copy the value, borrow it, insert an unchecked
615
- // ownership conversion to unowned at oldValue and then RAUW.
616
+ // points. To do so, we copy the value, borrow it, and insert an unchecked
617
+ // ownership conversion to unowned at all uses that are terminator uses.
618
+ //
619
+ // We need to insert the conversion since if we have a non-argument
620
+ // guaranteed value since its scope will end before the terminator so we
621
+ // need to convert the value to unowned early.
616
622
//
617
- // We need to insert the conversion to ensure that we do not violate
618
- // ownership propagation rules of forwarding insts.
623
+ // TODO: Do we need a separate array here?
619
624
SmallVector<Operand *, 8 > oldValueUses (oldValue->getUses ());
620
625
for (auto *use : oldValueUses) {
621
626
if (auto *ti = dyn_cast<TermInst>(use->getUser ())) {
@@ -628,14 +633,12 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
628
633
}
629
634
}
630
635
}
636
+
631
637
auto extender = getLifetimeExtender ();
632
638
SILValue borrow =
633
639
extender.createPlusZeroBorrow (newValue, oldValue->getUses ());
634
640
SILBuilderWithScope builder (oldValue);
635
- auto *newInst = builder.createUncheckedOwnershipConversion (
636
- oldValue->getLoc (), borrow, OwnershipKind::Unowned);
637
- callbacks.createdNewInst (newInst);
638
- return replaceAllUsesAndErase (oldValue, newInst, callbacks);
641
+ return replaceAllUsesAndErase (oldValue, borrow, callbacks);
639
642
}
640
643
case OwnershipKind::Owned: {
641
644
// If we have an unowned value that we want to replace with an owned value,
@@ -646,13 +649,15 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
646
649
647
650
// Otherwise, insert a copy of the owned value and lifetime extend that over
648
651
// all uses of the value and then RAUW.
652
+ //
653
+ // NOTE: For terminator uses, we funnel the use through an
654
+ // unchecked_ownership_conversion to ensure that we can end the lifetime of
655
+ // our owned/guaranteed value before the terminator.
649
656
SmallVector<Operand *, 8 > oldValueUses (oldValue->getUses ());
650
657
for (auto *use : oldValueUses) {
651
658
if (auto *ti = dyn_cast<TermInst>(use->getUser ())) {
652
659
if (ti->isFunctionExiting ()) {
653
660
SILBuilderWithScope builder (ti);
654
- // We insert this to ensure that we can extend our owned value's
655
- // lifetime to before the function end point.
656
661
auto *newInst = builder.createUncheckedOwnershipConversion (
657
662
ti->getLoc (), use->get (), OwnershipKind::Unowned);
658
663
callbacks.createdNewInst (newInst);
@@ -663,10 +668,7 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
663
668
auto extender = getLifetimeExtender ();
664
669
SILValue copy = extender.createPlusZeroCopy (newValue, oldValue->getUses ());
665
670
SILBuilderWithScope builder (oldValue);
666
- auto *newInst = builder.createUncheckedOwnershipConversion (
667
- oldValue->getLoc (), copy, OwnershipKind::Unowned);
668
- callbacks.createdNewInst (newInst);
669
- auto result = replaceAllUsesAndErase (oldValue, newInst, callbacks);
671
+ auto result = replaceAllUsesAndErase (oldValue, copy, callbacks);
670
672
return result;
671
673
}
672
674
}
0 commit comments