@@ -662,6 +662,13 @@ bool getAllBorrowIntroducingValues(SILValue value,
662
662
// / introducer, then we return a .some(BorrowScopeIntroducingValue).
663
663
BorrowedValue getSingleBorrowIntroducingValue (SILValue inputValue);
664
664
665
+ // / The algorithm that is used to determine what the verifier will consider to
666
+ // / be transitive uses of the given address. Used to implement \see
667
+ // / findTransitiveUses.
668
+ bool findTransitiveUsesForAddress (
669
+ SILValue address, SmallVectorImpl<Operand *> &foundUses,
670
+ std::function<void (Operand *)> *onError = nullptr);
671
+
665
672
class InteriorPointerOperandKind {
666
673
public:
667
674
enum Kind : uint8_t {
@@ -805,7 +812,7 @@ struct InteriorPointerOperand {
805
812
}
806
813
807
814
// / Return the base BorrowedValue of the incoming value's operand.
808
- BorrowedValue getSingleBaseValue () const {
815
+ BorrowedValue getSingleBorrowedValue () const {
809
816
return getSingleBorrowIntroducingValue (operand->get ());
810
817
}
811
818
@@ -840,14 +847,6 @@ struct InteriorPointerOperand {
840
847
onError);
841
848
}
842
849
843
- // / The algorithm that is used to determine what the verifier will consider to
844
- // / be transitive uses of the given address. Used to implement \see
845
- // / findTransitiveUses.
846
- static bool
847
- findTransitiveUsesForAddress (SILValue address,
848
- SmallVectorImpl<Operand *> &foundUses,
849
- std::function<void (Operand *)> *onError = nullptr );
850
-
851
850
Operand *operator ->() { return operand; }
852
851
const Operand *operator ->() const { return operand; }
853
852
Operand *operator *() { return operand; }
@@ -860,23 +859,70 @@ struct InteriorPointerOperand {
860
859
: operand(op), kind(kind) {}
861
860
};
862
861
863
- // / Utility to check if an address may originate from a borrowed value. If so,
862
+ // / Utility to check if an address may originate from an OSSA value. If so,
864
863
// / then uses of the address cannot be replaced without ensuring that they are
865
- // / also within the same scope.
864
+ // / also within the same owned lifetime or borrow scope.
866
865
// /
867
- // / If mayBeBorrowed is false, then there is no enclosing borrow scope and
868
- // / interiorPointerOp is irrelevant.
866
+ // / If hasOwnership() is false, then there is no enclosing lifetime or borrow
867
+ // / scope and interiorPointerOp is irrelevant.
869
868
// /
870
- // / If mayBeBorrowed is true, then interiorPointerOp refers to the operand that
869
+ // / If hasOwnership() is true, then interiorPointerOp refers to the operand that
871
870
// / converts a non-address value into the address from which the contructor's
872
871
// / address is derived. If the best-effort to find an InteriorPointerOperand
873
872
// / fails, then interiorPointerOp remains invalid, and clients must be
874
873
// / conservative.
875
- struct BorrowedAddress {
876
- bool mayBeBorrowed = true ;
877
- InteriorPointerOperand interiorPointerOp;
874
+ // /
875
+ // / TODO: Handle implicit borrow scopes once they are legal in SIL. The operand
876
+ // / of the base will be owned but mayBeBorrowed will remain true.
877
+ struct AddressOwnership {
878
+ AccessBase base;
879
+
880
+ AddressOwnership () = default ;
881
+
882
+ AddressOwnership (SILValue address) : base(AccessBase::compute(address)) {
883
+ assert (address->getType ().isAddress ());
884
+ }
878
885
879
- BorrowedAddress (SILValue address);
886
+ AddressOwnership (AccessBase base) : base(base) {}
887
+
888
+ operator bool () const { return bool (base); }
889
+
890
+ bool operator ==(const AddressOwnership &other) const {
891
+ return base.hasIdenticalAccessInfo (other.base );
892
+ }
893
+
894
+ bool operator !=(const AddressOwnership &other) const {
895
+ return !(*this == other);
896
+ }
897
+
898
+ // / Return true if this address may be derived from a value with a local OSSA
899
+ // / lifetime or borrow scope.
900
+ bool hasLocalOwnershipLifetime () const {
901
+ return base.hasLocalOwnershipLifetime ();
902
+ }
903
+
904
+ // / Return the OSSA value from which this address is derived. This may be
905
+ // / invalid even if hasOSSALifetime() is true in cases where the
906
+ // / InteriorPointerOperand is unrecognized.
907
+ SILValue getOwnershipReferenceRoot () const {
908
+ if (base.isReference ())
909
+ return base.getOwnershipReferenceRoot ();
910
+
911
+ return SILValue ();
912
+ }
913
+
914
+ // / Transitively compute uses of this base address.
915
+ bool findTransitiveUses (SmallVectorImpl<Operand *> &foundUses) {
916
+ return findTransitiveUsesForAddress (base.getBaseAddress (), foundUses);
917
+ }
918
+
919
+ // / Return true of all \p uses occur before the end of the address' lifetime
920
+ // / or borrow scope.
921
+ // /
922
+ // / Precondition: all \p uses are dominated by the beginning of the address'
923
+ // / lifetime or borrow scope.
924
+ bool areUsesWithinLifetime (ArrayRef<Operand *> uses,
925
+ DeadEndBlocks &deadEndBlocks) const ;
880
926
};
881
927
882
928
class OwnedValueIntroducerKind {
0 commit comments