@@ -258,47 +258,74 @@ class FindAccessBaseVisitor
258
258
using SuperTy = FindAccessVisitorImpl<FindAccessBaseVisitor>;
259
259
260
260
protected:
261
- Optional<SILValue> base;
261
+ // If the optional baseVal is set, then a result was found. If the SILValue
262
+ // within the optional is invalid, then there are multiple inconsistent base
263
+ // addresses (this may currently happen with RawPointer phis).
264
+ Optional<SILValue> baseVal;
265
+ // If the kind optional is set, then 'baseVal' is a valid
266
+ // AccessBase. 'baseVal' may be a valid SILValue while kind optional has no
267
+ // value if an invalid address producer was detected, via a call to
268
+ // visitNonAccess.
269
+ Optional<AccessBase::Kind> kindVal;
262
270
263
271
public:
264
272
FindAccessBaseVisitor (NestedAccessType nestedAccessTy,
265
273
StorageCastTy storageCastTy)
266
274
: FindAccessVisitorImpl(nestedAccessTy, storageCastTy) {}
267
275
268
276
// Returns the accessed address or an invalid SILValue.
269
- SILValue findBase (SILValue sourceAddr) && {
277
+ SILValue findPossibleBaseAddress (SILValue sourceAddr) && {
270
278
reenterUseDef (sourceAddr);
271
- return base.getValueOr (SILValue ());
279
+ return baseVal.getValueOr (SILValue ());
280
+ }
281
+
282
+ AccessBase findBase (SILValue sourceAddr) && {
283
+ reenterUseDef (sourceAddr);
284
+ if (!baseVal || !kindVal)
285
+ return AccessBase ();
286
+
287
+ return AccessBase (baseVal.getValue (), kindVal.getValue ());
272
288
}
273
289
274
290
void setResult (SILValue foundBase) {
275
- if (!base )
276
- base = foundBase;
277
- else if (base .getValue () != foundBase)
278
- base = SILValue ();
291
+ if (!baseVal )
292
+ baseVal = foundBase;
293
+ else if (baseVal .getValue () != foundBase)
294
+ baseVal = SILValue ();
279
295
}
280
296
281
297
// MARK: AccessPhiVisitor::UseDefVisitor implementation.
282
298
283
- bool isResultValid () const { return base && bool (base.getValue ()); }
299
+ // Keep going as long as baseVal is valid regardless of kindVal.
300
+ bool isResultValid () const { return baseVal && bool (baseVal.getValue ()); }
284
301
285
- void invalidateResult () { base = SILValue (); }
302
+ void invalidateResult () {
303
+ baseVal = SILValue ();
304
+ kindVal = None;
305
+ }
286
306
287
- Optional<SILValue> saveResult () const { return base ; }
307
+ Optional<SILValue> saveResult () const { return baseVal ; }
288
308
289
- void restoreResult (Optional<SILValue> result) { base = result; }
309
+ void restoreResult (Optional<SILValue> result) { baseVal = result; }
290
310
291
311
void addUnknownOffset () { return ; }
292
312
293
313
// MARK: visitor implementation.
294
314
295
315
SILValue visitBase (SILValue base, AccessStorage::Kind kind) {
296
316
setResult (base);
317
+ if (!baseVal.getValue ()) {
318
+ kindVal = None;
319
+ } else {
320
+ assert (!kindVal || kindVal.getValue () == kind);
321
+ kindVal = kind;
322
+ }
297
323
return SILValue ();
298
324
}
299
325
300
326
SILValue visitNonAccess (SILValue value) {
301
327
setResult (value);
328
+ kindVal = None;
302
329
return SILValue ();
303
330
}
304
331
@@ -322,7 +349,7 @@ SILValue swift::getTypedAccessAddress(SILValue address) {
322
349
SILValue accessAddress =
323
350
FindAccessBaseVisitor (NestedAccessType::StopAtAccessBegin,
324
351
StopAtStorageCast)
325
- .findBase (address);
352
+ .findPossibleBaseAddress (address);
326
353
assert (accessAddress->getType ().isAddress ());
327
354
return accessAddress;
328
355
}
@@ -334,14 +361,14 @@ SILValue swift::getAccessScope(SILValue address) {
334
361
assert (address->getType ().isAddress ());
335
362
return FindAccessBaseVisitor (NestedAccessType::StopAtAccessBegin,
336
363
IgnoreStorageCast)
337
- .findBase (address);
364
+ .findPossibleBaseAddress (address);
338
365
}
339
366
340
367
// This is allowed to be called on a non-address pointer type.
341
368
SILValue swift::getAccessBase (SILValue address) {
342
369
return FindAccessBaseVisitor (NestedAccessType::IgnoreAccessBegin,
343
370
IgnoreStorageCast)
344
- .findBase (address);
371
+ .findPossibleBaseAddress (address);
345
372
}
346
373
347
374
static bool isLetForBase (SILValue base) {
@@ -510,6 +537,12 @@ void AccessRepresentation::print(raw_ostream &os) const {
510
537
// MARK: AccessBase
511
538
// ===----------------------------------------------------------------------===//
512
539
540
+ AccessBase AccessBase::compute (SILValue sourceAddress) {
541
+ return FindAccessBaseVisitor (NestedAccessType::IgnoreAccessBegin,
542
+ IgnoreStorageCast)
543
+ .findBase (sourceAddress);
544
+ }
545
+
513
546
AccessBase::AccessBase (SILValue base, Kind kind)
514
547
: AccessRepresentation(base, kind)
515
548
{
0 commit comments