@@ -125,7 +125,8 @@ class AccessPhiVisitor
125125 phiArg->getIncomingPhiValues (pointerWorklist);
126126 }
127127
128- void visitStorageCast (SingleValueInstruction *cast, Operand *sourceOper) {
128+ void visitStorageCast (SingleValueInstruction *cast, Operand *sourceOper,
129+ AccessStorageCast) {
129130 // Allow conversions to/from pointers and addresses on disjoint phi paths
130131 // only if the underlying useDefVisitor allows it.
131132 if (storageCastTy == IgnoreStorageCast)
@@ -209,7 +210,8 @@ class FindAccessVisitorImpl : public AccessUseDefChainVisitor<Impl, SILValue> {
209210 return this ->asImpl ().visitNonAccess (phiArg);
210211 }
211212
212- SILValue visitStorageCast (SingleValueInstruction *, Operand *sourceAddr) {
213+ SILValue visitStorageCast (SingleValueInstruction *, Operand *sourceAddr,
214+ AccessStorageCast cast) {
213215 assert (storageCastTy == IgnoreStorageCast);
214216 return sourceAddr->get ();
215217 }
@@ -331,11 +333,12 @@ class FindAccessBaseVisitor
331333 }
332334
333335 // Override visitStorageCast to avoid seeing through arbitrary address casts.
334- SILValue visitStorageCast (SingleValueInstruction *cast, Operand *sourceAddr) {
336+ SILValue visitStorageCast (SingleValueInstruction *svi, Operand *sourceAddr,
337+ AccessStorageCast cast) {
335338 if (storageCastTy == StopAtStorageCast)
336- return visitNonAccess (cast );
339+ return visitNonAccess (svi );
337340
338- return SuperTy::visitStorageCast (cast , sourceAddr);
341+ return SuperTy::visitStorageCast (svi , sourceAddr, cast );
339342 }
340343};
341344
@@ -1062,11 +1065,13 @@ namespace {
10621065// AccessStorage object for all projection paths.
10631066class FindAccessStorageVisitor
10641067 : public FindAccessVisitorImpl<FindAccessStorageVisitor> {
1068+ using SuperTy = FindAccessVisitorImpl<FindAccessStorageVisitor>;
10651069
10661070public:
10671071 struct Result {
10681072 Optional<AccessStorage> storage;
10691073 SILValue base;
1074+ Optional<AccessStorageCast> seenCast;
10701075 };
10711076
10721077private:
@@ -1102,6 +1107,8 @@ class FindAccessStorageVisitor
11021107 // may be multiple global_addr bases for identical storage.
11031108 SILValue getBase () const { return result.base ; }
11041109
1110+ Optional<AccessStorageCast> getCast () const { return result.seenCast ; }
1111+
11051112 // MARK: AccessPhiVisitor::UseDefVisitor implementation.
11061113
11071114 // A valid result requires valid storage, but not a valid base.
@@ -1128,22 +1135,41 @@ class FindAccessStorageVisitor
11281135 invalidateResult ();
11291136 return SILValue ();
11301137 }
1138+
1139+ SILValue visitStorageCast (SingleValueInstruction *svi, Operand *sourceOper,
1140+ AccessStorageCast cast) {
1141+ result.seenCast = result.seenCast ? std::max (*result.seenCast , cast) : cast;
1142+ return SuperTy::visitStorageCast (svi, sourceOper, cast);
1143+ }
11311144};
11321145
11331146} // end anonymous namespace
11341147
1148+ RelativeAccessStorageWithBase
1149+ RelativeAccessStorageWithBase::compute (SILValue address) {
1150+ FindAccessStorageVisitor visitor (NestedAccessType::IgnoreAccessBegin);
1151+ visitor.findStorage (address);
1152+ return {
1153+ address, {visitor.getStorage (), visitor.getBase ()}, visitor.getCast ()};
1154+ }
1155+
1156+ RelativeAccessStorageWithBase
1157+ RelativeAccessStorageWithBase::computeInScope (SILValue address) {
1158+ FindAccessStorageVisitor visitor (NestedAccessType::StopAtAccessBegin);
1159+ visitor.findStorage (address);
1160+ return {
1161+ address, {visitor.getStorage (), visitor.getBase ()}, visitor.getCast ()};
1162+ }
1163+
11351164AccessStorageWithBase
11361165AccessStorageWithBase::compute (SILValue sourceAddress) {
1137- FindAccessStorageVisitor visitor (NestedAccessType::IgnoreAccessBegin);
1138- visitor.findStorage (sourceAddress);
1139- return {visitor.getStorage (), visitor.getBase ()};
1166+ return RelativeAccessStorageWithBase::compute (sourceAddress).storageWithBase ;
11401167}
11411168
11421169AccessStorageWithBase
11431170AccessStorageWithBase::computeInScope (SILValue sourceAddress) {
1144- FindAccessStorageVisitor visitor (NestedAccessType::StopAtAccessBegin);
1145- visitor.findStorage (sourceAddress);
1146- return {visitor.getStorage (), visitor.getBase ()};
1171+ return RelativeAccessStorageWithBase::computeInScope (sourceAddress)
1172+ .storageWithBase ;
11471173}
11481174
11491175AccessStorage AccessStorage::compute (SILValue sourceAddress) {
0 commit comments