Skip to content

Commit 20ee76e

Browse files
committed
Add AccessBase::hasLocalOwnershipLifetime()
Replaces AccessStorage::isGuaranteedForFunction(). OSSA utilities need to determine whether two addresses with the same AccessStorage are directly substitutable without "fixing-up" the OSSA lifetime. Checking whether the access base is within a local borrow scope is the first step.
1 parent 1502083 commit 20ee76e

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

include/swift/SIL/MemAccessUtils.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,16 @@ class AccessBase : public AccessRepresentation {
610610
/// determined. Otherwise returns null.
611611
const ValueDecl *getDecl() const;
612612

613+
/// Return true if this base address may be derived from a reference that is
614+
/// only valid within a locally scoped OSSA lifetime. This is not true for
615+
/// scoped storage such as alloc_stack and @in argument. It can be
616+
/// independently assumed that addresses are only used within the scope of the
617+
/// storage object.
618+
///
619+
/// Useful to determine whether addresses with the same AccessStorage are in
620+
/// fact substitutable without fixing OSSA lifetime.
621+
bool hasLocalOwnershipLifetime() const;
622+
613623
void print(raw_ostream &os) const;
614624
void dump() const;
615625
};
@@ -745,10 +755,6 @@ class AccessStorage : public AccessRepresentation {
745755
return hasIdenticalAccessInfo(other);
746756
}
747757

748-
/// Return true if this storage is valid for all uses in a function without
749-
/// checking its lifetime.
750-
bool isGuaranteedForFunction() const;
751-
752758
/// Returns the ValueDecl for the underlying storage, if it can be
753759
/// determined. Otherwise returns null.
754760
const ValueDecl *getDecl() const;

lib/SIL/Utils/MemAccessUtils.cpp

+24-11
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,30 @@ const ValueDecl *AccessBase::getDecl() const {
642642
}
643643
}
644644

645+
bool AccessBase::hasLocalOwnershipLifetime() const {
646+
switch (getKind()) {
647+
case AccessBase::Argument:
648+
case AccessBase::Stack:
649+
case AccessBase::Global:
650+
return false;
651+
case AccessBase::Unidentified:
652+
// Unidentified storage may be nested within object access, but this is an
653+
// "escaped pointer", so it is not restricted to the object's borrow scope.
654+
return false;
655+
case AccessBase::Yield:
656+
// Yielded values have a local apply scope, but they never have the same
657+
// storage as yielded values from a different scope, so there is no need to
658+
// consider their local scope during substitution.
659+
return false;
660+
case AccessBase::Box:
661+
case AccessBase::Class:
662+
case AccessBase::Tail:
663+
return getReference()->getOwnershipKind() != OwnershipKind::None;
664+
case AccessBase::Nested:
665+
llvm_unreachable("unexpected storage");
666+
};
667+
}
668+
645669
void AccessBase::print(raw_ostream &os) const {
646670
AccessRepresentation::print(os);
647671
switch (getKind()) {
@@ -835,17 +859,6 @@ void AccessStorage::visitRoots(
835859
}
836860
}
837861

838-
bool AccessStorage::isGuaranteedForFunction() const {
839-
if (getKind() == AccessStorage::Argument) {
840-
return getArgument()->getArgumentConvention().isGuaranteedConvention();
841-
}
842-
if (isObjectAccess()) {
843-
return getRoot().getOwnershipKind() == OwnershipKind::Guaranteed
844-
&& isa<SILFunctionArgument>(getRoot());
845-
}
846-
return false;
847-
}
848-
849862
const ValueDecl *AccessStorage::getDecl() const {
850863
switch (getKind()) {
851864
case Box:

0 commit comments

Comments
 (0)