@@ -125,7 +125,8 @@ class AccessPhiVisitor
125
125
phiArg->getIncomingPhiValues (pointerWorklist);
126
126
}
127
127
128
- void visitStorageCast (SingleValueInstruction *cast, Operand *sourceOper) {
128
+ void visitStorageCast (SingleValueInstruction *cast, Operand *sourceOper,
129
+ AccessStorageCast) {
129
130
// Allow conversions to/from pointers and addresses on disjoint phi paths
130
131
// only if the underlying useDefVisitor allows it.
131
132
if (storageCastTy == IgnoreStorageCast)
@@ -209,7 +210,8 @@ class FindAccessVisitorImpl : public AccessUseDefChainVisitor<Impl, SILValue> {
209
210
return this ->asImpl ().visitNonAccess (phiArg);
210
211
}
211
212
212
- SILValue visitStorageCast (SingleValueInstruction *, Operand *sourceAddr) {
213
+ SILValue visitStorageCast (SingleValueInstruction *, Operand *sourceAddr,
214
+ AccessStorageCast cast) {
213
215
assert (storageCastTy == IgnoreStorageCast);
214
216
return sourceAddr->get ();
215
217
}
@@ -331,11 +333,12 @@ class FindAccessBaseVisitor
331
333
}
332
334
333
335
// 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) {
335
338
if (storageCastTy == StopAtStorageCast)
336
- return visitNonAccess (cast );
339
+ return visitNonAccess (svi );
337
340
338
- return SuperTy::visitStorageCast (cast , sourceAddr);
341
+ return SuperTy::visitStorageCast (svi , sourceAddr, cast );
339
342
}
340
343
};
341
344
@@ -1062,11 +1065,13 @@ namespace {
1062
1065
// AccessStorage object for all projection paths.
1063
1066
class FindAccessStorageVisitor
1064
1067
: public FindAccessVisitorImpl<FindAccessStorageVisitor> {
1068
+ using SuperTy = FindAccessVisitorImpl<FindAccessStorageVisitor>;
1065
1069
1066
1070
public:
1067
1071
struct Result {
1068
1072
Optional<AccessStorage> storage;
1069
1073
SILValue base;
1074
+ Optional<AccessStorageCast> seenCast;
1070
1075
};
1071
1076
1072
1077
private:
@@ -1102,6 +1107,8 @@ class FindAccessStorageVisitor
1102
1107
// may be multiple global_addr bases for identical storage.
1103
1108
SILValue getBase () const { return result.base ; }
1104
1109
1110
+ Optional<AccessStorageCast> getCast () const { return result.seenCast ; }
1111
+
1105
1112
// MARK: AccessPhiVisitor::UseDefVisitor implementation.
1106
1113
1107
1114
// A valid result requires valid storage, but not a valid base.
@@ -1128,22 +1135,41 @@ class FindAccessStorageVisitor
1128
1135
invalidateResult ();
1129
1136
return SILValue ();
1130
1137
}
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
+ }
1131
1144
};
1132
1145
1133
1146
} // end anonymous namespace
1134
1147
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
+
1135
1164
AccessStorageWithBase
1136
1165
AccessStorageWithBase::compute (SILValue sourceAddress) {
1137
- FindAccessStorageVisitor visitor (NestedAccessType::IgnoreAccessBegin);
1138
- visitor.findStorage (sourceAddress);
1139
- return {visitor.getStorage (), visitor.getBase ()};
1166
+ return RelativeAccessStorageWithBase::compute (sourceAddress).storageWithBase ;
1140
1167
}
1141
1168
1142
1169
AccessStorageWithBase
1143
1170
AccessStorageWithBase::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 ;
1147
1173
}
1148
1174
1149
1175
AccessStorage AccessStorage::compute (SILValue sourceAddress) {
0 commit comments