Skip to content

Commit 0ccc828

Browse files
authored
Merge pull request swiftlang#63835 from gottesmm/pr-f0822f891b024a92a1ee7695b6f73f03a9f8ae7d
[move-only] When emitting a deinit for a move only struct with only trivial fields, use an end_lifetime instead of a destructure_struct.
2 parents f878cdd + f9f1118 commit 0ccc828

File tree

3 files changed

+118
-24
lines changed

3 files changed

+118
-24
lines changed

lib/SILGen/SILGenDestructor.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -538,11 +538,21 @@ void SILGenFunction::emitMoveOnlyMemberDestruction(SILValue selfValue,
538538
B.setInsertionPoint(contBlock);
539539
}
540540
} else {
541-
if (isa<StructDecl>(nom)) {
542-
auto *d = B.createDestructureStruct(cleanupLoc, selfValue,
543-
OwnershipKind::Owned);
544-
for (auto result : d->getResults()) {
545-
B.emitDestroyValueOperation(cleanupLoc, result);
541+
if (auto *sd = dyn_cast<StructDecl>(nom)) {
542+
if (llvm::any_of(sd->getStoredProperties(),
543+
[&](VarDecl *vd) {
544+
auto &lowering = getTypeLowering(vd->getType());
545+
return !lowering.isTrivial();
546+
})) {
547+
auto *d = B.createDestructureStruct(cleanupLoc, selfValue,
548+
OwnershipKind::Owned);
549+
for (auto result : d->getResults()) {
550+
B.emitDestroyValueOperation(cleanupLoc, result);
551+
}
552+
} else {
553+
// If we only contain trivial uses, we don't have anything to cleanup,
554+
// so just insert an end_lifetime.
555+
B.createEndLifetime(cleanupLoc, selfValue);
546556
}
547557
} else {
548558
auto *origBlock = B.getInsertionBB();

test/Interpreter/moveonly.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-move-only -Xfrontend -sil-verify-all) | %FileCheck %s
2+
3+
// REQUIRES: executable_test
4+
5+
// CHECK: MyInt: 5
6+
@inline(never)
7+
func printInt(_ x: Int) { print("MyInt: \(x)") }
8+
9+
@_moveOnly
10+
struct FD {
11+
var i = 5
12+
13+
deinit {
14+
printInt(i)
15+
}
16+
}
17+
18+
func main() {
19+
let x = FD()
20+
let _ = x
21+
}
22+
23+
main()

test/SILGen/moveonly_deinits.swift

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
// Test that makes sure that throughout the pipeline we properly handle
66
// conditional releases for trivial and non-trivial move only types.
77

8-
//////////////////////
9-
// Misc Declaration //
10-
//////////////////////
8+
////////////////////////////
9+
// MARK: Misc Declaration //
10+
////////////////////////////
1111

1212
class Klass {}
1313

14-
/////////////////////////
15-
// Struct Declarations //
16-
/////////////////////////
14+
///////////////////////////////
15+
// MARK: Struct Declarations //
16+
///////////////////////////////
17+
18+
@inline(never)
19+
func doSomething() {
20+
print("123")
21+
}
1722

1823
@_moveOnly
1924
struct KlassPairWithoutDeinit {
@@ -27,7 +32,7 @@ struct KlassPairWithDeinit {
2732
var rhs = Klass()
2833

2934
deinit {
30-
print("123")
35+
doSomething()
3136
}
3237
}
3338

@@ -43,7 +48,7 @@ struct IntPairWithDeinit {
4348
var k2: Int = 6
4449

4550
deinit {
46-
print("123")
51+
doSomething()
4752
}
4853
}
4954

@@ -54,9 +59,27 @@ func consumeKlassPairWithDeinit(_ x: __owned KlassPairWithDeinit) { }
5459

5560
var value: Bool { false }
5661

57-
//////////////////
58-
// Struct Tests //
59-
//////////////////
62+
//////////////////////////////////////
63+
// MARK: Struct Deinit Output Tests //
64+
//////////////////////////////////////
65+
66+
// SILGEN-LABEL: sil hidden [ossa] @$s16moveonly_deinits19KlassPairWithDeinitVfD : $@convention(method) (@owned KlassPairWithDeinit) -> () {
67+
// SILGEN: bb0([[ARG:%.*]] :
68+
// SILGEN: [[MARK:%.*]] = mark_must_check [consumable_and_assignable] [[ARG]]
69+
// SILGEN: ([[LHS:%.*]], [[RHS:%.*]]) = destructure_struct [[MARK]]
70+
// SILGEN: destroy_value [[LHS]]
71+
// SILGEN: destroy_value [[RHS]]
72+
// SILGEN: } // end sil function '$s16moveonly_deinits19KlassPairWithDeinitVfD'
73+
74+
// SILGEN-LABEL: sil hidden [ossa] @$s16moveonly_deinits17IntPairWithDeinitVfD : $@convention(method) (@owned IntPairWithDeinit) -> () {
75+
// SILGEN: bb0([[ARG:%.*]] :
76+
// SILGEN: [[MARKED:%.*]] = mark_must_check [consumable_and_assignable] [[ARG]]
77+
// SILGEN: end_lifetime [[MARKED]]
78+
// SILGEN: } // end sil function '$s16moveonly_deinits17IntPairWithDeinitVfD'
79+
80+
////////////////////////
81+
// MARK: Struct Tests //
82+
////////////////////////
6083

6184
// SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits24testIntPairWithoutDeinityyF : $@convention(thin) () -> () {
6285
// SILGEN: [[BOX:%.*]] = alloc_box
@@ -259,9 +282,9 @@ public func testKlassPairWithDeinit() {
259282
}
260283
}
261284

262-
///////////////////////
263-
// Enum Declarations //
264-
///////////////////////
285+
/////////////////////////////
286+
// MARK: Enum Declarations //
287+
/////////////////////////////
265288

266289
@_moveOnly
267290
enum KlassEnumPairWithoutDeinit {
@@ -275,7 +298,7 @@ enum KlassEnumPairWithDeinit {
275298
case rhs(Klass)
276299

277300
deinit {
278-
print("123")
301+
doSomething()
279302
}
280303
}
281304

@@ -291,7 +314,7 @@ enum IntEnumPairWithDeinit {
291314
case rhs(Int)
292315

293316
deinit {
294-
print("123")
317+
doSomething()
295318
}
296319
}
297320

@@ -300,9 +323,47 @@ func consumeIntEnumPairWithDeinit(_ x: __owned IntEnumPairWithDeinit) { }
300323
func consumeKlassEnumPairWithoutDeinit(_ x: __owned KlassEnumPairWithoutDeinit) { }
301324
func consumeKlassEnumPairWithDeinit(_ x: __owned KlassEnumPairWithDeinit) { }
302325

303-
////////////////
304-
// Enum Tests //
305-
////////////////
326+
////////////////////////////////////
327+
// MARK: Enum Deinit Output Tests //
328+
////////////////////////////////////
329+
330+
// SILGEN-LABEL: sil hidden [ossa] @$s16moveonly_deinits23KlassEnumPairWithDeinitOfD : $@convention(method) (@owned KlassEnumPairWithDeinit) -> () {
331+
// SILGEN: bb0([[ARG:%.*]] :
332+
// SILGEN: [[MARK:%.*]] = mark_must_check [consumable_and_assignable] [[ARG]]
333+
// SILGEN: switch_enum [[MARK]] : $KlassEnumPairWithDeinit, case #KlassEnumPairWithDeinit.lhs!enumelt: [[BB_LHS:bb[0-9]+]], case #KlassEnumPairWithDeinit.rhs!enumelt: [[BB_RHS:bb[0-9]+]]
334+
//
335+
// SILGEN: [[BB_LHS]]([[ARG:%.*]] :
336+
// SILGEN-NEXT: destroy_value [[ARG]]
337+
// SILGEN-NEXT: br [[BB_CONT:bb[0-9]+]]
338+
//
339+
// SILGEN: [[BB_RHS]]([[ARG:%.*]] :
340+
// SILGEN-NEXT: destroy_value [[ARG]]
341+
// SILGEN-NEXT: br [[BB_CONT]]
342+
//
343+
// SILGEN: [[BB_CONT]]:
344+
// SILGEN-NEXT: tuple ()
345+
// SILGEN-NEXT: return
346+
// SILGEN: } // end sil function '$s16moveonly_deinits23KlassEnumPairWithDeinitOfD'
347+
348+
// SILGEN-LABEL: sil hidden [ossa] @$s16moveonly_deinits21IntEnumPairWithDeinitOfD : $@convention(method) (@owned IntEnumPairWithDeinit) -> () {
349+
// SILGEN: bb0([[ARG:%.*]] :
350+
// SILGEN: [[MARK:%.*]] = mark_must_check [consumable_and_assignable] [[ARG]]
351+
// SILGEN: switch_enum [[MARK]] : $IntEnumPairWithDeinit, case #IntEnumPairWithDeinit.lhs!enumelt: [[BB_LHS:bb[0-9]+]], case #IntEnumPairWithDeinit.rhs!enumelt: [[BB_RHS:bb[0-9]+]]
352+
//
353+
// SILGEN: [[BB_LHS]]([[ARG:%.*]] :
354+
// SILGEN-NEXT: br [[BB_CONT:bb[0-9]+]]
355+
//
356+
// SILGEN: [[BB_RHS]]([[ARG:%.*]] :
357+
// SILGEN-NEXT: br [[BB_CONT]]
358+
//
359+
// SILGEN: [[BB_CONT]]:
360+
// SILGEN-NEXT: tuple ()
361+
// SILGEN-NEXT: return
362+
// SILGEN: } // end sil function '$s16moveonly_deinits21IntEnumPairWithDeinitOfD'
363+
364+
//////////////////////
365+
// MARK: Enum Tests //
366+
//////////////////////
306367

307368
// SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits28testIntEnumPairWithoutDeinityyF : $@convention(thin) () -> () {
308369
// SILGEN: [[BOX:%.*]] = alloc_box

0 commit comments

Comments
 (0)