Skip to content

Commit 74acec9

Browse files
authored
Merge pull request #70117 from eeckstein/fix-deinit-devirtualization
deinit-devirtualization: correctly handle drop_deinit for address types
2 parents ecc302b + 285c60d commit 74acec9

File tree

4 files changed

+13
-40
lines changed

4 files changed

+13
-40
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/Devirtualization.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
3636
precondition(type.isNominal, "non-copyable non-nominal types not supported, yet")
3737

3838
let result: Bool
39-
if type.nominal.hasValueDeinit && !destroy.hasDropDeinit {
39+
if type.nominal.hasValueDeinit && !destroy.shouldDropDeinit {
4040
guard let deinitFunc = context.lookupDeinit(ofNominal: type.nominal) else {
4141
return false
4242
}
@@ -58,6 +58,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
5858

5959
// Used to dispatch devirtualization tasks to `destroy_value` and `destroy_addr`.
6060
private protocol DevirtualizableDestroy : UnaryInstruction {
61+
var shouldDropDeinit: Bool { get }
6162
func createDeinitCall(to deinitializer: Function, _ context: some MutatingContext)
6263
func devirtualizeStructFields(_ context: some MutatingContext) -> Bool
6364
func devirtualizeEnumPayload(enumCase: EnumCase, in block: BasicBlock, _ context: some MutatingContext) -> Bool
@@ -67,8 +68,6 @@ private protocol DevirtualizableDestroy : UnaryInstruction {
6768
private extension DevirtualizableDestroy {
6869
var type: Type { operand.value.type }
6970

70-
var hasDropDeinit: Bool { operand.value.lookThoughOwnershipInstructions is DropDeinitInst }
71-
7271
func devirtualizeEnumPayloads(_ context: some MutatingContext) -> Bool {
7372
guard let cases = type.getEnumCases(in: parentFunction) else {
7473
return false
@@ -99,6 +98,8 @@ private extension DevirtualizableDestroy {
9998
}
10099

101100
extension DestroyValueInst : DevirtualizableDestroy {
101+
fileprivate var shouldDropDeinit: Bool { operand.value.lookThoughOwnershipInstructions is DropDeinitInst }
102+
102103
fileprivate func createDeinitCall(to deinitializer: Function, _ context: some MutatingContext) {
103104
let builder = Builder(before: self, context)
104105
let subs = context.getContextSubstitutionMap(for: type)
@@ -162,6 +163,11 @@ extension DestroyValueInst : DevirtualizableDestroy {
162163
}
163164

164165
extension DestroyAddrInst : DevirtualizableDestroy {
166+
fileprivate var shouldDropDeinit: Bool {
167+
// The deinit is always called by a destroy_addr. There must not be a `drop_deinit` as operand.
168+
false
169+
}
170+
165171
fileprivate func createDeinitCall(to deinitializer: Function, _ context: some MutatingContext) {
166172
let builder = Builder(before: self, context)
167173
let subs = context.getContextSubstitutionMap(for: destroyedAddress.type)

test/SILOptimizer/devirt_deinits.sil

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,18 +235,6 @@ bb0(%0 : $*E2):
235235
return %r : $()
236236
}
237237

238-
// CHECK-LABEL: sil [ossa] @test_drop_deinit_addr :
239-
// CHECK: %1 = drop_deinit %0
240-
// CHECK: end_lifetime %1
241-
// CHECK: } // end sil function 'test_drop_deinit_addr'
242-
sil [ossa] @test_drop_deinit_addr : $@convention(thin) (@in S1) -> () {
243-
bb0(%0 : $*S1):
244-
%1 = drop_deinit %0 : $*S1
245-
destroy_addr %1 : $*S1
246-
%r = tuple()
247-
return %r : $()
248-
}
249-
250238
// CHECK-LABEL: sil [ossa] @test_two_field_drop_deinit_addr :
251239
// CHECK: %1 = drop_deinit %0
252240
// CHECK: [[A1:%.*]] = struct_element_addr %1 : $*S4, #S4.a
@@ -261,7 +249,10 @@ bb0(%0 : $*S1):
261249
sil [ossa] @test_two_field_drop_deinit_addr : $@convention(thin) (@in S4) -> () {
262250
bb0(%0 : $*S4):
263251
%1 = drop_deinit %0 : $*S4
264-
destroy_addr %1 : $*S4
252+
%2 = struct_element_addr %1 : $*S4, #S4.a
253+
destroy_addr %2 : $*S1
254+
%4 = struct_element_addr %1 : $*S4, #S4.b
255+
destroy_addr %4 : $*S2
265256
%r = tuple()
266257
return %r : $()
267258
}

test/SILOptimizer/moveonly_deinit_devirtualization.sil

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -329,18 +329,6 @@ bb0(%0 : @owned $StructDeinit):
329329
return %9999 : $()
330330
}
331331

332-
// CHECK-LABEL: sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in StructDeinit) -> () {
333-
// CHECK: %1 = drop_deinit %0
334-
// CHECK-NEXT: end_lifetime %1
335-
// CHECK: } // end sil function 'dropDeinitOnIndirectStruct'
336-
sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in StructDeinit) -> () {
337-
bb0(%0 : $*StructDeinit):
338-
%1 = drop_deinit %0 : $*StructDeinit
339-
destroy_addr %1 : $*StructDeinit
340-
%9999 = tuple()
341-
return %9999 : $()
342-
}
343-
344332
sil @$s4main5KlassCfD : $@convention(method) (@owned Klass) -> ()
345333
sil @$s4main5KlassCACycfc : $@convention(method) (@owned Klass) -> @owned Klass
346334
sil @$s4main5KlassCfd : $@convention(method) (@guaranteed Klass) -> @owned Builtin.NativeObject

test/SILOptimizer/moveonly_deinit_devirtualization_library_evolution.sil

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,18 +331,6 @@ bb0(%0 : @owned $StructDeinit):
331331
return %9999 : $()
332332
}
333333

334-
// CHECK-LABEL: sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in StructDeinit) -> () {
335-
// CHECK: %1 = drop_deinit %0
336-
// CHECK-NEXT: end_lifetime %1
337-
// CHECK: } // end sil function 'dropDeinitOnIndirectStruct'
338-
sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in StructDeinit) -> () {
339-
bb0(%0 : $*StructDeinit):
340-
%1 = drop_deinit %0 : $*StructDeinit
341-
destroy_addr %1 : $*StructDeinit
342-
%9999 = tuple()
343-
return %9999 : $()
344-
}
345-
346334
sil @$s4main5KlassCfD : $@convention(method) (@owned Klass) -> ()
347335
sil @$s4main5KlassCACycfc : $@convention(method) (@owned Klass) -> @owned Klass
348336
sil @$s4main5KlassCfd : $@convention(method) (@guaranteed Klass) -> @owned Builtin.NativeObject

0 commit comments

Comments
 (0)