Skip to content

Commit dd75d2e

Browse files
Merge pull request #81854 from nate-chandler/rdar152195094
[DestroyAddrHoisting] Don't destructure NE aggs.
2 parents f31cdb3 + a9c31b9 commit dd75d2e

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ struct AccessPathWithBase {
12811281
//
12821282
// Returns false if the access path couldn't be computed.
12831283
bool visitProductLeafAccessPathNodes(
1284-
SILValue address, TypeExpansionContext tec, SILModule &module,
1284+
SILValue address, TypeExpansionContext tec, SILFunction &function,
12851285
std::function<void(AccessPath::PathNode, SILType)> visitor);
12861286

12871287
inline AccessPath AccessPath::compute(SILValue address) {

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ AccessPathWithBase AccessPathWithBase::computeInScope(SILValue address) {
14371437
}
14381438

14391439
bool swift::visitProductLeafAccessPathNodes(
1440-
SILValue address, TypeExpansionContext tec, SILModule &module,
1440+
SILValue address, TypeExpansionContext tec, SILFunction &function,
14411441
std::function<void(AccessPath::PathNode, SILType)> visitor) {
14421442
auto rootPath = AccessPath::compute(address);
14431443
if (!rootPath.isValid()) {
@@ -1461,15 +1461,17 @@ bool swift::visitProductLeafAccessPathNodes(
14611461
visitor(AccessPath::PathNode(node), silType);
14621462
continue;
14631463
}
1464-
if (decl->isCxxNonTrivial()) {
1464+
if (decl->isCxxNonTrivial() || !silType.isEscapable(function) ||
1465+
silType.isMoveOnly()) {
14651466
visitor(AccessPath::PathNode(node), silType);
14661467
continue;
14671468
}
14681469
unsigned index = 0;
14691470
for (auto *field : decl->getStoredProperties()) {
14701471
auto *fieldNode = node->getChild(index);
14711472
worklist.push_back(
1472-
{silType.getFieldType(field, module, tec), fieldNode});
1473+
{silType.getFieldType(field, function.getModule(), tec),
1474+
fieldNode});
14731475
++index;
14741476
}
14751477
} else {

lib/SILOptimizer/Transforms/DestroyAddrHoisting.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ bool HoistDestroys::foldBarrier(SILInstruction *barrier,
604604
SmallPtrSet<AccessPath::PathNode, 16> trivialLeaves;
605605

606606
bool succeeded = visitProductLeafAccessPathNodes(
607-
storageRoot, typeExpansionContext, module,
607+
storageRoot, typeExpansionContext, *function,
608608
[&](AccessPath::PathNode node, SILType ty) {
609609
if (ty.isTrivial(*function))
610610
return;
@@ -765,7 +765,7 @@ bool HoistDestroys::checkFoldingBarrier(
765765
bool alreadySawLeaf = false;
766766
bool alreadySawTrivialSubleaf = false;
767767
auto succeeded = visitProductLeafAccessPathNodes(
768-
address, typeExpansionContext, module,
768+
address, typeExpansionContext, *function,
769769
[&](AccessPath::PathNode node, SILType ty) {
770770
if (ty.isTrivial(*function)) {
771771
bool inserted = !trivialLeaves.insert(node).second;

test/SILOptimizer/hoist_destroy_addr.sil

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
// RUN: %target-sil-opt -sil-print-types -opt-mode=none -enable-sil-verify-all %s -compute-side-effects -destroy-addr-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEB --check-prefix=CHECK-DEB
2-
// RUN: %target-sil-opt -sil-print-types -opt-mode=speed -enable-sil-verify-all %s -compute-side-effects -destroy-addr-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKOPT --check-prefix=CHECK-OPT
1+
// RUN: %target-sil-opt -sil-print-types -enable-experimental-feature LifetimeDependence -opt-mode=none -enable-sil-verify-all %s -compute-side-effects -destroy-addr-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEB --check-prefix=CHECK-DEB
2+
// RUN: %target-sil-opt -sil-print-types -enable-experimental-feature LifetimeDependence -opt-mode=speed -enable-sil-verify-all %s -compute-side-effects -destroy-addr-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKOPT --check-prefix=CHECK-OPT
33
//
44
// TODO: migrate the remaining tests from destroy_hoisting.sil.
55

66
// REQUIRES: swift_in_compiler
7+
// REQUIRES: swift_feature_LifetimeDependence
78

89
sil_stage canonical
910

@@ -1224,3 +1225,58 @@ bb0(%0 : @owned $Nontrivial):
12241225
%14 = tuple ()
12251226
return %14 : $()
12261227
}
1228+
1229+
struct Regular {
1230+
var storage: Builtin.NativeObject
1231+
}
1232+
struct NEGutless: ~Escapable {
1233+
let ptr: UnsafeRawPointer?
1234+
}
1235+
struct NEMarker : ~Escapable {}
1236+
struct NEAggregate: ~Escapable {
1237+
var ne: NEGutless
1238+
let regular: Regular
1239+
1240+
@lifetime(copy ne) init(ne: NEMarker)
1241+
}
1242+
1243+
// CHECK-LABEL: sil [ossa] @no_destructure_nonescapable : {{.*}} {
1244+
// CHECK: bb0([[AGGREGATE:%[^,]+]] :
1245+
// CHECK: destroy_addr [[AGGREGATE]]
1246+
// CHECK-LABEL: } // end sil function 'no_destructure_nonescapable'
1247+
sil [ossa] @no_destructure_nonescapable : $@convention(method) (@in NEAggregate) -> () {
1248+
bb0(%aggregate : $*NEAggregate):
1249+
%regular = struct_element_addr %aggregate, #NEAggregate.regular
1250+
%regular_copy = alloc_stack $Regular
1251+
copy_addr %regular to [init] %regular_copy
1252+
destroy_addr %regular_copy
1253+
dealloc_stack %regular_copy
1254+
destroy_addr %aggregate
1255+
%retval = tuple ()
1256+
return %retval
1257+
}
1258+
1259+
struct NCGutless: ~Copyable {
1260+
let ptr: UnsafeRawPointer?
1261+
}
1262+
struct NCAggregate: ~Copyable {
1263+
var ne: NCGutless
1264+
let regular: Regular
1265+
deinit {}
1266+
}
1267+
1268+
// CHECK-LABEL: sil [ossa] @no_destructure_noncopyable : {{.*}} {
1269+
// CHECK: bb0([[AGGREGATE:%[^,]+]] :
1270+
// CHECK: destroy_addr [[AGGREGATE]]
1271+
// CHECK-LABEL: } // end sil function 'no_destructure_noncopyable'
1272+
sil [ossa] @no_destructure_noncopyable : $@convention(method) (@in NCAggregate) -> () {
1273+
bb0(%aggregate : $*NCAggregate):
1274+
%regular = struct_element_addr %aggregate, #NCAggregate.regular
1275+
%regular_copy = alloc_stack $Regular
1276+
copy_addr %regular to [init] %regular_copy
1277+
destroy_addr %regular_copy
1278+
dealloc_stack %regular_copy
1279+
destroy_addr %aggregate
1280+
%retval = tuple ()
1281+
return %retval
1282+
}

0 commit comments

Comments
 (0)