@@ -786,6 +786,7 @@ bool BorrowingOperand::visitExtendedScopeEndingUses(
786
786
return visitScopeEndingUses (visitor, visitUnknownUse);
787
787
}
788
788
789
+ // This should be equivalent to SwiftCompilerSources, BorrowedValue.
789
790
SILValue BorrowingOperand::getBorrowIntroducingUserResult () const {
790
791
switch (kind) {
791
792
case BorrowingOperandKind::Invalid:
@@ -800,8 +801,16 @@ SILValue BorrowingOperand::getBorrowIntroducingUserResult() const {
800
801
return SILValue ();
801
802
802
803
case BorrowingOperandKind::BeginBorrow:
803
- case BorrowingOperandKind::BorrowedFrom: {
804
804
return cast<SingleValueInstruction>(op->getUser ());
805
+
806
+ case BorrowingOperandKind::BorrowedFrom: {
807
+ // A reborrow introduces a new borrow scope, a guaranteed forwarding phi
808
+ // does not.
809
+ auto *bfi = cast<BorrowedFromInst>(op->getUser ());
810
+ if (bfi->isReborrow ()) {
811
+ return bfi->getBorrowedValue ();
812
+ }
813
+ return SILValue ();
805
814
}
806
815
case BorrowingOperandKind::Branch: {
807
816
auto *bi = cast<BranchInst>(op->getUser ());
@@ -811,29 +820,57 @@ SILValue BorrowingOperand::getBorrowIntroducingUserResult() const {
811
820
llvm_unreachable (" covered switch" );
812
821
}
813
822
814
- SILValue BorrowingOperand::getScopeIntroducingUserResult () {
823
+ SILValue BorrowingOperand::getScopeIntroducingUserResult () const {
815
824
switch (kind) {
816
- case BorrowingOperandKind::Invalid:
817
- case BorrowingOperandKind::Yield:
818
- case BorrowingOperandKind::Apply:
819
- case BorrowingOperandKind::TryApply:
820
- return SILValue ();
821
-
822
825
case BorrowingOperandKind::BeginAsyncLet:
823
826
case BorrowingOperandKind::PartialApplyStack:
824
- case BorrowingOperandKind::MarkDependenceNonEscaping:
825
- case BorrowingOperandKind::BeginBorrow:
826
- case BorrowingOperandKind::BorrowedFrom:
827
827
case BorrowingOperandKind::StoreBorrow:
828
828
return cast<SingleValueInstruction>(op->getUser ());
829
829
830
+ case BorrowingOperandKind::MarkDependenceNonEscaping:
831
+ if (auto *mdi = cast<MarkDependenceInst>(op->getUser ())) {
832
+ if (mdi->hasScopedLifetime ())
833
+ return mdi;
834
+ }
835
+ return SILValue ();
836
+
830
837
case BorrowingOperandKind::BeginApply:
831
838
return cast<BeginApplyInst>(op->getUser ())->getTokenResult ();
832
839
833
- case BorrowingOperandKind::Branch: {
834
- PhiOperand phiOp (op);
835
- return phiOp.getValue ();
840
+ default :
841
+ return getBorrowIntroducingUserResult ();
836
842
}
843
+ llvm_unreachable (" covered switch" );
844
+ }
845
+
846
+ SILValue BorrowingOperand::getDependentUserResult () const {
847
+ switch (kind) {
848
+ case BorrowingOperandKind::BorrowedFrom: {
849
+ auto *bfi = cast<BorrowedFromInst>(op->getUser ());
850
+ if (!bfi->isReborrow ())
851
+ return bfi;
852
+
853
+ return SILValue ();
854
+ }
855
+ case BorrowingOperandKind::MarkDependenceNonEscaping: {
856
+ auto *mdi = cast<MarkDependenceInst>(op->getUser ());
857
+ assert (mdi->isNonEscaping () && " escaping dependencies don't borrow" );
858
+ if (!mdi->hasScopedLifetime ())
859
+ return mdi;
860
+
861
+ return SILValue ();
862
+ }
863
+ case BorrowingOperandKind::Invalid:
864
+ case BorrowingOperandKind::BeginBorrow:
865
+ case BorrowingOperandKind::StoreBorrow:
866
+ case BorrowingOperandKind::BeginApply:
867
+ case BorrowingOperandKind::Branch:
868
+ case BorrowingOperandKind::Apply:
869
+ case BorrowingOperandKind::TryApply:
870
+ case BorrowingOperandKind::Yield:
871
+ case BorrowingOperandKind::PartialApplyStack:
872
+ case BorrowingOperandKind::BeginAsyncLet:
873
+ return SILValue ();
837
874
}
838
875
llvm_unreachable (" covered switch" );
839
876
}
@@ -1044,6 +1081,9 @@ bool BorrowedValue::visitInteriorPointerOperandHelper(
1044
1081
}
1045
1082
1046
1083
auto result = borrowingOperand.getBorrowIntroducingUserResult ();
1084
+ if (!result) {
1085
+ result = borrowingOperand.getDependentUserResult ();
1086
+ }
1047
1087
for (auto *use : result->getUses ()) {
1048
1088
if (auto intPtrOperand = InteriorPointerOperand (use)) {
1049
1089
func (intPtrOperand);
@@ -1070,11 +1110,12 @@ bool BorrowedValue::visitInteriorPointerOperandHelper(
1070
1110
continue ;
1071
1111
}
1072
1112
1073
- // Look through object.
1113
+ // Look through object. SingleValueInstruction is overly restrictive but
1114
+ // rules out any interesting corner cases.
1074
1115
if (auto *svi = dyn_cast<SingleValueInstruction>(user)) {
1075
- if (Projection::isObjectProjection (svi )) {
1076
- for (SILValue result : user-> getResults ()) {
1077
- llvm::copy (result-> getUses (), std::back_inserter ( worklist) );
1116
+ if (ForwardingInstruction::isa (user )) {
1117
+ for (auto *use : svi-> getUses ()) {
1118
+ worklist. push_back (use );
1078
1119
}
1079
1120
continue ;
1080
1121
}
0 commit comments