Skip to content

Commit 50b358c

Browse files
authored
Merge pull request #72359 from meg-gupta/skiphismdi
Fix utilities that may see phis of mark_dependence [nonescaping]
2 parents 2603c84 + 3ebef80 commit 50b358c

File tree

6 files changed

+86
-32
lines changed

6 files changed

+86
-32
lines changed

lib/SIL/IR/SILInstruction.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,11 +1795,10 @@ bool SILInstruction::maySuspend() const {
17951795
return false;
17961796
}
17971797

1798-
static bool visitRecursivelyLifetimeEndingUses(
1799-
SILValue i,
1800-
bool &noUsers,
1801-
llvm::function_ref<bool(Operand *)> func)
1802-
{
1798+
static bool
1799+
visitRecursivelyLifetimeEndingUses(SILValue i, bool &noUsers,
1800+
llvm::function_ref<bool(Operand *)> func,
1801+
bool allowPhis) {
18031802
for (Operand *use : i->getConsumingUses()) {
18041803
noUsers = false;
18051804
if (isa<DestroyValueInst>(use->getUser())) {
@@ -1816,6 +1815,14 @@ static bool visitRecursivelyLifetimeEndingUses(
18161815
}
18171816
continue;
18181817
}
1818+
if (allowPhis) {
1819+
if (PhiOperand(use)) {
1820+
if (!func(use)) {
1821+
return false;
1822+
}
1823+
continue;
1824+
}
1825+
}
18191826
// FIXME: Handle store to indirect result
18201827

18211828
// There shouldn't be any dead-end consumptions of a nonescaping
@@ -1838,7 +1845,8 @@ static bool visitRecursivelyLifetimeEndingUses(
18381845
"forwarded to a destroy_value");
18391846
}
18401847
for (auto res : use->getUser()->getResults()) {
1841-
if (!visitRecursivelyLifetimeEndingUses(res, noUsers, func)) {
1848+
if (!visitRecursivelyLifetimeEndingUses(res, noUsers, func,
1849+
allowPhis)) {
18421850
return false;
18431851
}
18441852
}
@@ -1854,7 +1862,8 @@ PartialApplyInst::visitOnStackLifetimeEnds(
18541862
&& "only meaningful for OSSA stack closures");
18551863
bool noUsers = true;
18561864

1857-
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func)) {
1865+
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func,
1866+
/*allowPhis*/ false)) {
18581867
return false;
18591868
}
18601869
return !noUsers;
@@ -1866,7 +1875,8 @@ visitNonEscapingLifetimeEnds(llvm::function_ref<bool (Operand *)> func) const {
18661875
&& "only meaningful for nonescaping dependencies");
18671876
bool noUsers = true;
18681877

1869-
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func)) {
1878+
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, func,
1879+
/*allowPhis*/ true)) {
18701880
return false;
18711881
}
18721882
return !noUsers;

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ bool swift::findInnerTransitiveGuaranteedUses(
331331
if (endUse->getOperandOwnership() == OperandOwnership::Reborrow) {
332332
foundPointerEscape = true;
333333
}
334+
if (PhiOperand(endUse)) {
335+
assert(endUse->getOperandOwnership() ==
336+
OperandOwnership::ForwardingConsume);
337+
foundPointerEscape = true;
338+
}
334339
leafUse(endUse);
335340
return true;
336341
})) {
@@ -385,11 +390,18 @@ bool swift::findExtendedUsesOfSimpleBorrowedValue(
385390
break;
386391

387392
case OperandOwnership::TrivialUse:
388-
case OperandOwnership::ForwardingConsume:
389393
case OperandOwnership::DestroyingConsume:
390394
recordUse(use);
391395
break;
392396

397+
case OperandOwnership::ForwardingConsume: {
398+
if (PhiOperand(use)) {
399+
return false;
400+
}
401+
recordUse(use);
402+
break;
403+
}
404+
393405
case OperandOwnership::ForwardingUnowned:
394406
case OperandOwnership::PointerEscape:
395407
case OperandOwnership::Reborrow:
@@ -468,6 +480,11 @@ bool swift::findUsesOfSimpleValue(SILValue value,
468480
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
469481
return false;
470482
}
483+
if (PhiOperand(use)) {
484+
assert(use->getOperandOwnership() ==
485+
OperandOwnership::ForwardingConsume);
486+
return false;
487+
}
471488
usePoints->push_back(end);
472489
return true;
473490
})) {
@@ -971,6 +988,9 @@ bool BorrowedValue::visitExtendedScopeEndingUses(
971988
reborrows.insert(borrowedValue.value);
972989
return true;
973990
}
991+
if (auto phiOp = PhiOperand(scopeEndingUse)) {
992+
return false;
993+
}
974994
return visitor(scopeEndingUse);
975995
};
976996

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ PrunedLiveRange<LivenessWithDefs>::updateForBorrowingOperand(Operand *operand) {
238238
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
239239
return false;
240240
}
241+
if (PhiOperand(end)) {
242+
assert(end->getOperandOwnership() ==
243+
OperandOwnership::ForwardingConsume);
244+
return false;
245+
}
241246
updateForUse(end->getUser(), /*lifetimeEnding*/ false);
242247
return true;
243248
})) {

lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ bool Implementation::gatherUses(SILValue value) {
479479
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
480480
return false;
481481
}
482+
if (PhiOperand(end)) {
483+
assert(end->getOperandOwnership() ==
484+
OperandOwnership::ForwardingConsume);
485+
return false;
486+
}
482487
LLVM_DEBUG(llvm::dbgs() << " ++ Scope-ending use: ";
483488
end->getUser()->print(llvm::dbgs()));
484489
for (auto leafRange : leafRanges) {

lib/SILOptimizer/Utils/LexicalDestroyFolding.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,11 @@ bool findBorroweeUsage(Context const &context, BorroweeUsage &usage) {
636636
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
637637
return false;
638638
}
639+
if (PhiOperand(end)) {
640+
assert(end->getOperandOwnership() ==
641+
OperandOwnership::ForwardingConsume);
642+
return false;
643+
}
639644
recordUse(end);
640645
return true;
641646
})) {

test/SIL/lifetime_dependence_buffer_view_test.swift

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,10 @@
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
98
// REQUIRES: swift_in_compiler
10-
// REQUIRES: noncopyable_generics
11-
12-
// FIXME(NCG): This requires nonescaping Optionals.
13-
// XFAIL: *
149

1510
// TODO: Use real Range
1611
public struct FakeRange<Bound> {
@@ -67,7 +62,7 @@ public struct BufferView<Element> : ~Escapable {
6762
private var baseAddress: UnsafeRawPointer { start._rawValue }
6863
// TODO: Enable diagnostics once this initializer's store to temporary is handled
6964
// 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> {
70-
public init<Owner>(
65+
public init<Owner: ~Copyable & ~Escapable>(
7166
baseAddress: UnsafeRawPointer,
7267
count: Int,
7368
dependsOn owner: borrowing Owner
@@ -77,7 +72,7 @@ public struct BufferView<Element> : ~Escapable {
7772
)
7873
}
7974
// 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> {
80-
init<Owner>(
75+
init<Owner: ~Copyable & ~Escapable>(
8176
start index: BufferViewIndex<Element>,
8277
count: Int,
8378
dependsOn owner: borrowing Owner
@@ -113,6 +108,11 @@ extension BufferView {
113108

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

117117
public subscript(position: Index) -> Element {
118118
get {
@@ -134,30 +134,39 @@ extension BufferView {
134134
)
135135
}
136136
}
137+
138+
borrowing public func prefix(upTo index: BufferViewIndex<Element>) -> _borrow(self) Self {
139+
index == startIndex
140+
? Self(start: start, count: 0, dependsOn: copy self)
141+
: prefix(through: index.advanced(by: -1))
142+
}
143+
144+
borrowing public func prefix(through index: Index) -> _borrow(self) Self {
145+
let nc = distance(from: startIndex, to: index) &+ 1
146+
return Self(start: start, count: nc, dependsOn: copy self)
147+
}
148+
149+
consuming public func prefix(_ maxLength: Int) -> _consume(self) Self {
150+
precondition(maxLength >= 0, "Can't have a prefix of negative length.")
151+
let nc = maxLength < count ? maxLength : count
152+
return Self(start: start, count: nc, dependsOn: self)
153+
}
137154
}
138155

139-
extension Array {
140-
// var view: BufferView<Element> {
141-
// withUnsafeBufferPointer {
142-
// return BufferView(unsafeBuffer: $0, storage: self)
143-
// }
144-
// }
145-
// TODO: Implementation of getter should not need a temporary
146-
// rdar://123071321
147-
// CHECK: sil hidden @$sSa31lifetime_dependence_scope_fixupE4viewAA10BufferViewVyxGvg : $@convention(method) <Element> (@guaranteed Array<Element>) -> _scope(0) @owned BufferView<Element> {
148-
var view: BufferView<Element> {
149-
var _view : BufferView<Element>? // FIXME(NCG): This is not a thing. How did this work?
150-
withUnsafePointer(to:self) {
151-
_view = BufferView(baseAddress: $0, count: self.count, dependsOn: self)
156+
extension ContiguousArray {
157+
public var view: BufferView<Element> {
158+
borrowing _read {
159+
yield BufferView(
160+
baseAddress: _baseAddressIfContiguous!, count: count, dependsOn: self
161+
)
152162
}
153-
return _view!
154163
}
155164
}
156165

157-
public func array_view_element(a: [Int] , i: BufferViewIndex<Int>) -> Int {
166+
public func array_view_element(a: ContiguousArray<Int> , i: BufferViewIndex<Int>) -> Int {
158167
a.view[i]
159168
}
160169

161-
public func array_view_slice_element(a: [Int] , sliceIdx: FakeRange<BufferViewIndex<Int>>, Idx: BufferViewIndex<Int>) -> Int {
170+
public func array_view_slice_element(a: ContiguousArray<Int> , sliceIdx: FakeRange<BufferViewIndex<Int>>, Idx: BufferViewIndex<Int>) -> Int {
162171
a.view[sliceIdx][Idx]
163172
}

0 commit comments

Comments
 (0)