Skip to content

Commit 639f318

Browse files
committed
[AddressLowering] Cache ops before iteration.
Before iterating over an instruction's uses and deleting each, cache the list of uses. Otherwise, the for loop stops after the first instruction when it's deleted (and has its NextUse field cleared).
1 parent 424174c commit 639f318

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,8 @@ void OpaqueStorageAllocation::removeAllocation(SILValue value) {
11831183
storage.storageAddress = nullptr;
11841184

11851185
// It's only use should be dealloc_stacks.
1186-
for (Operand *use : allocInst->getUses()) {
1186+
SmallVector<Operand *, 4> uses(allocInst->getUses());
1187+
for (Operand *use : uses) {
11871188
pass.deleter.forceDelete(cast<DeallocStackInst>(use->getUser()));
11881189
}
11891190
pass.deleter.forceDelete(allocInst);

test/SILOptimizer/address_lowering.sil

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,61 @@ entry(%instance : @owned $Pair<T>):
12731273
return %retval : $()
12741274
}
12751275

1276+
/// Verify that alloc_stacks for which there is already a dealloc stack can be
1277+
/// deleted.
1278+
// CHECK-LABEL: sil [ossa] @partition : {{.*}} {
1279+
// CHECK: {{bb[0-9]+}}([[INDEX_OUT:%[^,]+]] : $*Self.Index, [[SELF:%[^,]+]] : $*Self):
1280+
// CHECK: [[MAYBE_INDEX_ADDR:%[^,]+]] = alloc_stack $Optional<Builtin.Int64>
1281+
// CHECK: try_apply {{%[^,]+}}<Self, Builtin.Int64>([[MAYBE_INDEX_ADDR]], [[SELF]]) : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection><τ_1_0> (@inout τ_0_0) -> (@out Optional<τ_1_0>, @error any Error), normal [[YES_BLOCK:bb[0-9]+]], error [[NO_BLOCK:bb[0-9]+]]
1282+
// CHECK: [[NO_BLOCK]]([[REGISTER_16:%[^,]+]] : @owned $any Error):
1283+
// CHECK: dealloc_stack [[MAYBE_INDEX_ADDR]]
1284+
// CHECK: br [[EXIT_ERROR:bb[0-9]+]]([[REGISTER_16]] : $any Error)
1285+
// CHECK: [[EXIT_ERROR]]([[ERROR_TO_THROW:%[^,]+]] : @owned $any Error):
1286+
// CHECK: throw [[ERROR_TO_THROW]]
1287+
// CHECK: [[YES_BLOCK]]
1288+
// CHECK: [[MAYBE_INDEX:%[^,]+]] = load [trivial] [[MAYBE_INDEX_ADDR]]
1289+
// CHECK: dealloc_stack [[MAYBE_INDEX_ADDR]]
1290+
// CHECK: switch_enum [[MAYBE_INDEX]] : $Optional<Builtin.Int64>, case #Optional.some!enumelt: [[SOME_BLOCK:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BLOCK:bb[0-9]+]]
1291+
// CHECK: [[NONE_BLOCK]]:
1292+
// CHECK: apply {{%[^,]+}}<Self>([[INDEX_OUT]], [[SELF]])
1293+
// CHECK: [[SOME_BLOCK]]([[SOME_INDEX:%[^,]+]] : $Builtin.Int64):
1294+
// CHECK: apply {{%[^,]+}}<Self>([[INDEX_OUT]], [[SOME_INDEX]])
1295+
// CHECK-LABEL: } // end sil function 'partition'
1296+
protocol MyCollection {
1297+
associatedtype Index
1298+
}
1299+
sil [ossa] @impl : $@convention(method) <τ_0_0 where τ_0_0 : MyCollection> (@inout τ_0_0) -> @out τ_0_0.Index
1300+
sil [ossa] @one : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection><τ_1_0> (@inout τ_0_0) -> (@out Optional<τ_1_0>, @error any Error)
1301+
sil [ossa] @startIndex : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection> (@in_guaranteed τ_0_0) -> @out τ_0_0.Index
1302+
sil [ossa] @index : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection> (Int) -> @out τ_0_0.Index
1303+
sil [ossa] @partition : $@convention(method) <Self where Self : MyCollection> (@inout Self) -> (@out Self.Index, @error any Error) {
1304+
bb0(%1 : $*Self):
1305+
%11 = function_ref @one : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection><τ_1_0> (@inout τ_0_0) -> (@out Optional<τ_1_0>, @error any Error)
1306+
try_apply %11<Self, Int>(%1) : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection><τ_1_0> (@inout τ_0_0) -> (@out Optional<τ_1_0>, @error any Error), normal bb1, error bb6
1307+
1308+
bb1(%13 : $Optional<Int>):
1309+
switch_enum %13 : $Optional<Int>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb3
1310+
1311+
bb2(%17 : $Int):
1312+
%28 = function_ref @index : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection> (Int) -> @out τ_0_0.Index
1313+
%29 = apply %28<Self>(%17) : $@convention(thin) <τ_0_0 where τ_0_0 : MyCollection> (Int) -> @out τ_0_0.Index
1314+
br exit_normal(%29 : $Self.Index)
1315+
1316+
bb3:
1317+
%34 = function_ref @impl : $@convention(method) <τ_0_0 where τ_0_0 : MyCollection> (@inout τ_0_0) -> @out τ_0_0.Index
1318+
%36 = apply %34<Self>(%1) : $@convention(method) <τ_0_0 where τ_0_0 : MyCollection> (@inout τ_0_0) -> @out τ_0_0.Index
1319+
br exit_normal(%36 : $Self.Index)
1320+
1321+
bb6(%41 : @owned $any Error):
1322+
br exit_error(%41 : $any Error)
1323+
1324+
exit_normal(%39 : @owned $Self.Index):
1325+
return %39 : $Self.Index
1326+
1327+
exit_error(%47 : @owned $any Error):
1328+
throw %47 : $any Error
1329+
}
1330+
12761331
sil hidden [ossa] @testBeginApplyDeadYield : $@convention(thin) <T> (@guaranteed TestGeneric<T>) -> () {
12771332
bb0(%0 : @guaranteed $TestGeneric<T>):
12781333
%2 = class_method %0 : $TestGeneric<T>, #TestGeneric.borrowedGeneric!read : <T> (TestGeneric<T>) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0
@@ -1541,3 +1596,4 @@ bb0(%0 : @guaranteed $T):
15411596
destroy_value %3 : $U
15421597
return %6 : $U
15431598
}
1599+

0 commit comments

Comments
 (0)