Skip to content

Commit b980d0c

Browse files
authored
Merge pull request swiftlang#29075 from gottesmm/pr-d55400f45418e4362a9634920318153134a33ce7
[di] When emitting element addresses to destroy fields, use begin_access [deinit].
2 parents 6f0f16e + b4cf1af commit b980d0c

7 files changed

+62
-28
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ SILType DIMemoryObjectInfo::getElementType(unsigned EltNo) const {
212212
Module, MemorySILType, EltNo, isNonDelegatingInit());
213213
}
214214

215-
/// computeTupleElementAddress - Given a tuple element number (in the flattened
216-
/// sense) return a pointer to a leaf element of the specified number.
217-
SILValue DIMemoryObjectInfo::emitElementAddress(
215+
/// Given a tuple element number (in the flattened sense) return a pointer to a
216+
/// leaf element of the specified number, so we can insert destroys for it.
217+
SILValue DIMemoryObjectInfo::emitElementAddressForDestroy(
218218
unsigned EltNo, SILLocation Loc, SILBuilder &B,
219-
llvm::SmallVectorImpl<std::pair<SILValue, SILValue>> &EndBorrowList) const {
219+
SmallVectorImpl<std::pair<SILValue, EndScopeKind>> &EndScopeList) const {
220220
SILValue Ptr = getUninitializedValue();
221221
bool IsSelf = isNonDelegatingInit();
222222
auto &Module = MemoryInst->getModule();
@@ -260,7 +260,7 @@ SILValue DIMemoryObjectInfo::emitElementAddress(
260260
if (isa<ClassDecl>(NTD) && Ptr->getType().isAddress()) {
261261
SILValue Original = Ptr;
262262
SILValue Borrowed = Ptr = B.createLoadBorrow(Loc, Ptr);
263-
EndBorrowList.emplace_back(Borrowed, Original);
263+
EndScopeList.emplace_back(Borrowed, EndScopeKind::Borrow);
264264
}
265265
}
266266
auto expansionContext = TypeExpansionContext(B.getFunction());
@@ -277,12 +277,13 @@ SILValue DIMemoryObjectInfo::emitElementAddress(
277277
if (Ptr.getOwnershipKind() != ValueOwnershipKind::Guaranteed) {
278278
Original = Ptr;
279279
Borrowed = Ptr = B.createBeginBorrow(Loc, Ptr);
280+
EndScopeList.emplace_back(Borrowed, EndScopeKind::Borrow);
280281
}
281282
Ptr = B.createRefElementAddr(Loc, Ptr, VD);
282-
if (Original) {
283-
assert(Borrowed);
284-
EndBorrowList.emplace_back(Borrowed, Original);
285-
}
283+
Ptr = B.createBeginAccess(
284+
Loc, Ptr, SILAccessKind::Deinit, SILAccessEnforcement::Static,
285+
false /*noNestedConflict*/, false /*fromBuiltin*/);
286+
EndScopeList.emplace_back(Ptr, EndScopeKind::Access);
286287
}
287288

288289
PointeeType = FieldType;

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,13 @@ class DIMemoryObjectInfo {
212212
return MemoryInst->isDelegatingSelfAllocated();
213213
}
214214

215+
enum class EndScopeKind { Borrow, Access };
216+
215217
/// Given an element number (in the flattened sense) return a pointer to a
216218
/// leaf element of the specified number.
217-
SILValue emitElementAddress(
219+
SILValue emitElementAddressForDestroy(
218220
unsigned TupleEltNo, SILLocation Loc, SILBuilder &B,
219-
SmallVectorImpl<std::pair<SILValue, SILValue>> &EndBorrowList) const;
221+
SmallVectorImpl<std::pair<SILValue, EndScopeKind>> &EndScopeList) const;
220222

221223
/// Return the swift type of the specified element.
222224
SILType getElementType(unsigned EltNo) const;

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,14 +2303,26 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
23032303
B.setInsertionPoint(TrueBB->begin());
23042304
SILValue EltPtr;
23052305
{
2306-
llvm::SmallVector<std::pair<SILValue, SILValue>, 4> EndBorrowList;
2307-
EltPtr = TheMemory.emitElementAddress(Elt, Loc, B, EndBorrowList);
2306+
using EndScopeKind = DIMemoryObjectInfo::EndScopeKind;
2307+
SmallVector<std::pair<SILValue, EndScopeKind>, 4> EndScopeList;
2308+
EltPtr =
2309+
TheMemory.emitElementAddressForDestroy(Elt, Loc, B, EndScopeList);
23082310
if (auto *DA = B.emitDestroyAddrAndFold(Loc, EltPtr))
23092311
Destroys.push_back(DA);
2310-
while (!EndBorrowList.empty()) {
2311-
SILValue Borrowed, Original;
2312-
std::tie(Borrowed, Original) = EndBorrowList.pop_back_val();
2313-
B.createEndBorrow(Loc, Borrowed, Original);
2312+
while (!EndScopeList.empty()) {
2313+
SILValue value;
2314+
EndScopeKind kind;
2315+
std::tie(value, kind) = EndScopeList.pop_back_val();
2316+
2317+
switch (kind) {
2318+
case EndScopeKind::Borrow:
2319+
B.createEndBorrow(Loc, value);
2320+
continue;
2321+
case EndScopeKind::Access:
2322+
B.createEndAccess(Loc, value, false /*can abort*/);
2323+
continue;
2324+
}
2325+
llvm_unreachable("Covered switch isn't covered!");
23142326
}
23152327
}
23162328
B.setInsertionPoint(ContBB->begin());
@@ -2364,15 +2376,27 @@ handleConditionalDestroys(SILValue ControlVariableAddr) {
23642376
// Utilities.
23652377

23662378
auto destroyMemoryElement = [&](SILLocation Loc, unsigned Elt) {
2367-
llvm::SmallVector<std::pair<SILValue, SILValue>, 4> EndBorrowList;
2379+
using EndScopeKind = DIMemoryObjectInfo::EndScopeKind;
2380+
SmallVector<std::pair<SILValue, EndScopeKind>, 4> EndScopeList;
23682381
SILValue EltPtr =
2369-
TheMemory.emitElementAddress(Elt, Loc, B, EndBorrowList);
2382+
TheMemory.emitElementAddressForDestroy(Elt, Loc, B, EndScopeList);
23702383
if (auto *DA = B.emitDestroyAddrAndFold(Loc, EltPtr))
23712384
Destroys.push_back(DA);
2372-
while (!EndBorrowList.empty()) {
2373-
SILValue Borrowed, Original;
2374-
std::tie(Borrowed, Original) = EndBorrowList.pop_back_val();
2375-
B.createEndBorrow(Loc, Borrowed, Original);
2385+
2386+
while (!EndScopeList.empty()) {
2387+
SILValue value;
2388+
EndScopeKind kind;
2389+
std::tie(value, kind) = EndScopeList.pop_back_val();
2390+
2391+
switch (kind) {
2392+
case EndScopeKind::Borrow:
2393+
B.createEndBorrow(Loc, value);
2394+
continue;
2395+
case EndScopeKind::Access:
2396+
B.createEndAccess(Loc, value, false /*can abort*/);
2397+
continue;
2398+
}
2399+
llvm_unreachable("Covered switch isn't covered!");
23762400
}
23772401
};
23782402

test/SILOptimizer/definite_init_failable_initializers_objc.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ class Cat : FakeNSObject {
4949

5050
// CHECK: bb1:
5151
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr [[ARG2]] : $Cat, #Cat.x
52-
// CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
52+
// CHECK-NEXT: [[FIELD_ADDR_ACCESS:%.*]] = begin_access [deinit] [static] [[FIELD_ADDR]]
53+
// CHECK-NEXT: destroy_addr [[FIELD_ADDR_ACCESS]] : $*LifetimeTracked
54+
// CHECK-NEXT: end_access [[FIELD_ADDR_ACCESS]]
5355
// CHECK-NEXT: strong_release [[ARG2]]
5456
// CHECK-NEXT: [[RELOAD_FROM_BOX:%.*]] = load [[SELF_BOX]]
5557
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type

test/SILOptimizer/definite_init_markuninitialized_derivedself.sil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
195195
// Now we destroy the stored value.
196196
// CHECK: [[SELF:%[0-9]+]] = load_borrow [[SELFBOX]]
197197
// CHECK: [[SELF_FIELD:%.*]] = ref_element_addr [[SELF]]
198-
// CHECK: destroy_addr [[SELF_FIELD]]
198+
// CHECK: [[SELF_FIELD_ACCESS:%.*]] = begin_access [deinit] [static] [[SELF_FIELD]]
199+
// CHECK: destroy_addr [[SELF_FIELD_ACCESS]]
200+
// CHECK: end_access [[SELF_FIELD_ACCESS]]
199201
// CHECK: end_borrow [[SELF]]
200202
//
201203
// And then perform dealloc_partial_ref.

test/SILOptimizer/definite_init_markuninitialized_rootself.sil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
109109
// CHECK: end_borrow [[BORROWED_SELF]]
110110
// CHECK: [[BORROWED_SELF:%.*]] = begin_borrow [[SELF]]
111111
// CHECK: [[SELF_FIELD:%.*]] = ref_element_addr [[BORROWED_SELF]]
112-
// CHECK: destroy_addr [[SELF_FIELD]]
112+
// CHECK: [[SELF_FIELD_ACCESS:%.*]] = begin_access [deinit] [static] [[SELF_FIELD]]
113+
// CHECK: destroy_addr [[SELF_FIELD_ACCESS]]
114+
// CHECK: end_access [[SELF_FIELD_ACCESS]]
113115
// CHECK: end_borrow [[BORROWED_SELF]]
114116
// CHECK: [[METATYPE:%[0-9]+]] = metatype $@thick RootClassWithNontrivialStoredProperties.Type
115117
// CHECK: dealloc_partial_ref [[SELF]] : $RootClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick RootClassWithNontrivialStoredProperties.Type

test/SILOptimizer/di-conditional-destroy-scope.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
// REQUIRES: objc_interop
77

88

9-
// CHECK: [[ADR:%.*]] = ref_element_addr %{{.*}} : $RecursibleDirectoryContentsGenerator, #RecursibleDirectoryContentsGenerator.fileSystem, loc {{.*}}:38:5, scope 2
10-
// CHECK: destroy_addr [[ADR]] : $*FileSystem, loc {{.*}}:38:5, scope 2
9+
// CHECK: [[ADR:%.*]] = ref_element_addr %{{.*}} : $RecursibleDirectoryContentsGenerator, #RecursibleDirectoryContentsGenerator.fileSystem, loc {{.*}}:39:5, scope 2
10+
// CHECK: [[ADR_ACCESS:%.*]] = begin_access [deinit] [static] [[ADR]]
11+
// CHECK: destroy_addr [[ADR_ACCESS]] : $*FileSystem, loc {{.*}}:39:5, scope 2
1112

1213

1314
import Foundation

0 commit comments

Comments
 (0)