Skip to content

Commit e9e3ce7

Browse files
committed
Add findOwnershipReferenceAggregate().
Simple convenience on top of findOwnershipReferenceRoot to handle guaranteed values forwarded through struct/tuple extract. Note: eventually this should be handled by a ReferenceRoot abstraction that stores the component path.
1 parent 20ee76e commit e9e3ce7

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

include/swift/SIL/MemAccessUtils.h

+5
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ SILValue findReferenceRoot(SILValue ref);
204204
/// Find the first owned root of the reference.
205205
SILValue findOwnershipReferenceRoot(SILValue ref);
206206

207+
/// Find the aggregate containing the first owned root of the
208+
/// reference. Identical to findOwnershipReferenceRoot, but looks through
209+
/// struct_extract, tuple_extract, etc.
210+
SILValue findOwnershipReferenceAggregate(SILValue ref);
211+
207212
/// Return true if \p address points to a let-variable.
208213
///
209214
/// let-variables are only written during let-variable initialization, which is

include/swift/SIL/SILInstruction.h

+5
Original file line numberDiff line numberDiff line change
@@ -4937,6 +4937,8 @@ class ConversionInst : public SingleValueInstruction {
49374937

49384938
/// A conversion inst that produces a static OwnershipKind set upon the
49394939
/// instruction's construction.
4940+
///
4941+
/// The first operand is the ownership equivalent source.
49404942
class OwnershipForwardingConversionInst : public ConversionInst,
49414943
public OwnershipForwardingMixin {
49424944
protected:
@@ -7877,6 +7879,8 @@ class TermInst : public NonValueInstruction {
78777879
TermKind getTermKind() const { return TermKind(getKind()); }
78787880

78797881
/// Returns true if this is a transformation terminator.
7882+
///
7883+
/// The first operand is the transformed source.
78807884
bool isTransformationTerminator() const {
78817885
switch (getTermKind()) {
78827886
case TermKind::UnwindInst:
@@ -9396,6 +9400,7 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
93969400
}
93979401
}
93989402

9403+
/// The first operand is the ownership equivalent source.
93999404
class OwnershipForwardingMultipleValueInstruction
94009405
: public MultipleValueInstruction,
94019406
public OwnershipForwardingMixin {

lib/SIL/Utils/MemAccessUtils.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,38 @@ SILValue swift::findOwnershipReferenceRoot(SILValue ref) {
799799
return FindReferenceRoot(true /*preserveOwnership*/).findRoot(ref);
800800
}
801801

802+
/// Find the first owned aggregate containing the reference, or simply the
803+
/// reference root if no aggregate is found.
804+
///
805+
/// TODO: Add a component path to a ReferenceRoot abstraction and handle
806+
/// that within FindReferenceRoot.
807+
SILValue swift::findOwnershipReferenceAggregate(SILValue ref) {
808+
SILValue root = ref;
809+
while(true) {
810+
root = findOwnershipReferenceRoot(root);
811+
if (!root)
812+
return root;
813+
if (isa<FirstArgOwnershipForwardingSingleValueInst>(root)
814+
|| isa<OwnershipForwardingConversionInst>(root)
815+
|| isa<OwnershipForwardingSelectEnumInstBase>(root)
816+
|| isa<OwnershipForwardingMultipleValueInstruction>(root)) {
817+
root = root->getDefiningInstruction()->getOperand(0);
818+
continue;
819+
}
820+
if (auto *arg = dyn_cast<SILArgument>(root)) {
821+
if (auto *term = arg->getSingleTerminator()) {
822+
if (term->isTransformationTerminator()) {
823+
assert(OwnershipForwardingTermInst::isa(term));
824+
root = term->getOperand(0);
825+
continue;
826+
}
827+
}
828+
}
829+
break;
830+
}
831+
return root;
832+
}
833+
802834
//===----------------------------------------------------------------------===//
803835
// MARK: AccessStorage
804836
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)