Skip to content

Commit 1502083

Browse files
committed
Implement AccessBase::compute(SILValue sourceAddress)
Missing implementation from the previous commit that introduced AccessBase. Now we can directly ask for an AccessBase value.
1 parent 5f11629 commit 1502083

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,17 @@ class AccessRepresentation {
546546
/// require traversing phis.
547547
class AccessBase : public AccessRepresentation {
548548
public:
549+
/// Return an AccessBase for the formally accessed variable pointed to by \p
550+
/// sourceAddress.
551+
///
552+
/// \p sourceAddress may be an address type or Builtin.RawPointer.
553+
///
554+
/// If \p sourceAddress is within a formal access scope, which does not have
555+
/// "Unsafe" enforcement, then this always returns the valid base.
556+
///
557+
/// If \p sourceAddress is not within a formal access scope, or within an
558+
/// "Unsafe" scope, then this finds the formal base if possible,
559+
/// otherwise returning an invalid base.
549560
static AccessBase compute(SILValue sourceAddress);
550561

551562
// Do not add any members to this class. AccessBase can be copied as

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -258,47 +258,74 @@ class FindAccessBaseVisitor
258258
using SuperTy = FindAccessVisitorImpl<FindAccessBaseVisitor>;
259259

260260
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;
262270

263271
public:
264272
FindAccessBaseVisitor(NestedAccessType nestedAccessTy,
265273
StorageCastTy storageCastTy)
266274
: FindAccessVisitorImpl(nestedAccessTy, storageCastTy) {}
267275

268276
// Returns the accessed address or an invalid SILValue.
269-
SILValue findBase(SILValue sourceAddr) && {
277+
SILValue findPossibleBaseAddress(SILValue sourceAddr) && {
270278
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());
272288
}
273289

274290
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();
279295
}
280296

281297
// MARK: AccessPhiVisitor::UseDefVisitor implementation.
282298

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()); }
284301

285-
void invalidateResult() { base = SILValue(); }
302+
void invalidateResult() {
303+
baseVal = SILValue();
304+
kindVal = None;
305+
}
286306

287-
Optional<SILValue> saveResult() const { return base; }
307+
Optional<SILValue> saveResult() const { return baseVal; }
288308

289-
void restoreResult(Optional<SILValue> result) { base = result; }
309+
void restoreResult(Optional<SILValue> result) { baseVal = result; }
290310

291311
void addUnknownOffset() { return; }
292312

293313
// MARK: visitor implementation.
294314

295315
SILValue visitBase(SILValue base, AccessStorage::Kind kind) {
296316
setResult(base);
317+
if (!baseVal.getValue()) {
318+
kindVal = None;
319+
} else {
320+
assert(!kindVal || kindVal.getValue() == kind);
321+
kindVal = kind;
322+
}
297323
return SILValue();
298324
}
299325

300326
SILValue visitNonAccess(SILValue value) {
301327
setResult(value);
328+
kindVal = None;
302329
return SILValue();
303330
}
304331

@@ -322,7 +349,7 @@ SILValue swift::getTypedAccessAddress(SILValue address) {
322349
SILValue accessAddress =
323350
FindAccessBaseVisitor(NestedAccessType::StopAtAccessBegin,
324351
StopAtStorageCast)
325-
.findBase(address);
352+
.findPossibleBaseAddress(address);
326353
assert(accessAddress->getType().isAddress());
327354
return accessAddress;
328355
}
@@ -334,14 +361,14 @@ SILValue swift::getAccessScope(SILValue address) {
334361
assert(address->getType().isAddress());
335362
return FindAccessBaseVisitor(NestedAccessType::StopAtAccessBegin,
336363
IgnoreStorageCast)
337-
.findBase(address);
364+
.findPossibleBaseAddress(address);
338365
}
339366

340367
// This is allowed to be called on a non-address pointer type.
341368
SILValue swift::getAccessBase(SILValue address) {
342369
return FindAccessBaseVisitor(NestedAccessType::IgnoreAccessBegin,
343370
IgnoreStorageCast)
344-
.findBase(address);
371+
.findPossibleBaseAddress(address);
345372
}
346373

347374
static bool isLetForBase(SILValue base) {
@@ -510,6 +537,12 @@ void AccessRepresentation::print(raw_ostream &os) const {
510537
// MARK: AccessBase
511538
//===----------------------------------------------------------------------===//
512539

540+
AccessBase AccessBase::compute(SILValue sourceAddress) {
541+
return FindAccessBaseVisitor(NestedAccessType::IgnoreAccessBegin,
542+
IgnoreStorageCast)
543+
.findBase(sourceAddress);
544+
}
545+
513546
AccessBase::AccessBase(SILValue base, Kind kind)
514547
: AccessRepresentation(base, kind)
515548
{

0 commit comments

Comments
 (0)