Skip to content

Commit 124de27

Browse files
committed
While verifiying mark_dependence [nonescaping], skip visiting phis
TODO: Handle verification of mark_dependence [nonescaping] with phi uses separately in the ownership verifier
1 parent 1be8e86 commit 124de27

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

lib/SIL/IR/SILInstruction.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,11 +1792,10 @@ bool SILInstruction::maySuspend() const {
17921792
return false;
17931793
}
17941794

1795-
static bool visitRecursivelyLifetimeEndingUses(
1796-
SILValue i,
1797-
bool &noUsers,
1798-
llvm::function_ref<bool(Operand *)> func)
1799-
{
1795+
static bool
1796+
visitRecursivelyLifetimeEndingUses(SILValue i, bool &noUsers,
1797+
llvm::function_ref<bool(Operand *)> func,
1798+
bool skipVisitingPhis) {
18001799
for (Operand *use : i->getConsumingUses()) {
18011800
noUsers = false;
18021801
if (isa<DestroyValueInst>(use->getUser())) {
@@ -1813,6 +1812,11 @@ static bool visitRecursivelyLifetimeEndingUses(
18131812
}
18141813
continue;
18151814
}
1815+
if (skipVisitingPhis) {
1816+
if (PhiOperand(use)) {
1817+
continue;
1818+
}
1819+
}
18161820
// FIXME: Handle store to indirect result
18171821

18181822
// There shouldn't be any dead-end consumptions of a nonescaping
@@ -1835,7 +1839,8 @@ static bool visitRecursivelyLifetimeEndingUses(
18351839
"forwarded to a destroy_value");
18361840
}
18371841
for (auto res : use->getUser()->getResults()) {
1838-
if (!visitRecursivelyLifetimeEndingUses(res, noUsers, func)) {
1842+
if (!visitRecursivelyLifetimeEndingUses(res, noUsers, func,
1843+
skipVisitingPhis)) {
18391844
return false;
18401845
}
18411846
}
@@ -1851,7 +1856,8 @@ PartialApplyInst::visitOnStackLifetimeEnds(
18511856
&& "only meaningful for OSSA stack closures");
18521857
bool noUsers = true;
18531858

1854-
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func)) {
1859+
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func,
1860+
/*skipVisitingPhis*/ false)) {
18551861
return false;
18561862
}
18571863
return !noUsers;
@@ -1863,7 +1869,8 @@ visitNonEscapingLifetimeEnds(llvm::function_ref<bool (Operand *)> func) const {
18631869
&& "only meaningful for nonescaping dependencies");
18641870
bool noUsers = true;
18651871

1866-
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func)) {
1872+
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func,
1873+
/*skipVisitingPhis*/ true)) {
18671874
return false;
18681875
}
18691876
return !noUsers;

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ bool SILValueOwnershipChecker::gatherNonGuaranteedUsers(
261261
guaranteedPhiVerifier.verifyReborrows(
262262
cast<BeginBorrowInst>(op->getUser()));
263263
}
264+
// TODO: Verify mark_dependence [nonescaping]'s transitive phi uses.
264265
}
265266

266267
return foundError;

test/SIL/lifetime_dependence_buffer_view_test.swift

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// RUN: -disable-experimental-parser-round-trip \
33
// RUN: -enable-experimental-feature NonescapableTypes \
44
// RUN: -enable-experimental-feature NoncopyableGenerics \
5-
// RUN: -enable-experimental-lifetime-dependence-inference \
65
// RUN: -disable-lifetime-dependence-diagnostics
76

87
// REQUIRES: asserts
@@ -64,7 +63,7 @@ public struct BufferView<Element> : ~Escapable {
6463
private var baseAddress: UnsafeRawPointer { start._rawValue }
6564
// TODO: Enable diagnostics once this initializer's store to temporary is handled
6665
// CHECK: sil @$s31lifetime_dependence_scope_fixup10BufferViewV11baseAddress5count9dependsOnACyxGSVYls_Siqd__htclufC : $@convention(method) <Element><Owner> (UnsafeRawPointer, Int, @in_guaranteed Owner, @thin BufferView<Element>.Type) -> _scope(1) @owned BufferView<Element> {
67-
public init<Owner>(
66+
public init<Owner: ~Copyable & ~Escapable>(
6867
baseAddress: UnsafeRawPointer,
6968
count: Int,
7069
dependsOn owner: borrowing Owner
@@ -74,7 +73,7 @@ public struct BufferView<Element> : ~Escapable {
7473
)
7574
}
7675
// CHECK: sil hidden @$s31lifetime_dependence_scope_fixup10BufferViewV5start5count9dependsOnACyxGAA0eF5IndexVyxGYls_Siqd__htclufC : $@convention(method) <Element><Owner> (BufferViewIndex<Element>, Int, @in_guaranteed Owner, @thin BufferView<Element>.Type) -> _scope(1) @owned BufferView<Element> {
77-
init<Owner>(
76+
init<Owner: ~Copyable & ~Escapable>(
7877
start index: BufferViewIndex<Element>,
7978
count: Int,
8079
dependsOn owner: borrowing Owner
@@ -110,6 +109,11 @@ extension BufferView {
110109

111110
public var startIndex: Index { start }
112111
public var endIndex: Index { start.advanced(by: count) }
112+
113+
@inlinable @inline(__always)
114+
public func distance(from start: Index, to end: Index) -> Int {
115+
start.distance(to: end)
116+
}
113117

114118
public subscript(position: Index) -> Element {
115119
get {
@@ -131,6 +135,23 @@ extension BufferView {
131135
)
132136
}
133137
}
138+
139+
borrowing public func prefix(upTo index: BufferViewIndex<Element>) -> _borrow(self) Self {
140+
index == startIndex
141+
? Self(start: start, count: 0, dependsOn: copy self)
142+
: prefix(through: index.advanced(by: -1))
143+
}
144+
145+
borrowing public func prefix(through index: Index) -> _borrow(self) Self {
146+
let nc = distance(from: startIndex, to: index) &+ 1
147+
return Self(start: start, count: nc, dependsOn: copy self)
148+
}
149+
150+
consuming public func prefix(_ maxLength: Int) -> _consume(self) Self {
151+
precondition(maxLength >= 0, "Can't have a prefix of negative length.")
152+
let nc = maxLength < count ? maxLength : count
153+
return Self(start: start, count: nc, dependsOn: self)
154+
}
134155
}
135156

136157
extension Array {

0 commit comments

Comments
 (0)