Skip to content

Commit 8238b94

Browse files
committed
[AddressLowering] Handle unowned copies.
Lower the `strong_copy_unowned_value` and `unowned_copy_value` to `load_unowned` and `store_unowned` respectively.
1 parent 526996a commit 8238b94

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,6 +3483,14 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
34833483
pass.deleter.forceDelete(sei);
34843484
}
34853485

3486+
void visitStrongCopyUnownedValueInst(StrongCopyUnownedValueInst *scuvi) {
3487+
auto sourceAddr = addrMat.materializeAddress(use->get());
3488+
SILValue value =
3489+
builder.createLoadUnowned(scuvi->getLoc(), sourceAddr, IsNotTake);
3490+
scuvi->replaceAllUsesWith(value);
3491+
pass.deleter.forceDelete(scuvi);
3492+
}
3493+
34863494
void visitStrongCopyWeakValueInst(StrongCopyWeakValueInst *scwvi) {
34873495
auto sourceAddr = addrMat.materializeAddress(use->get());
34883496
SILValue value =
@@ -4103,6 +4111,15 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
41034111
rewriteUnconditionalCheckedCastInst(uncondCheckedCast, pass);
41044112
}
41054113

4114+
void visitUnownedCopyValueInst(UnownedCopyValueInst *uci) {
4115+
auto &storage = pass.valueStorageMap.getStorage(uci);
4116+
auto destAddr = addrMat.recursivelyMaterializeStorage(
4117+
storage, /*intoPhiOperand=*/false);
4118+
4119+
builder.createStoreUnowned(uci->getLoc(), uci->getOperand(), destAddr,
4120+
IsInitialization);
4121+
}
4122+
41064123
void visitWeakCopyValueInst(WeakCopyValueInst *wcsvi) {
41074124
auto &storage = pass.valueStorageMap.getStorage(wcsvi);
41084125
auto destAddr = addrMat.recursivelyMaterializeStorage(

test/SILOptimizer/address_lowering.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,7 @@ bb0(%instance : @owned $T):
27202720
%retval = tuple ()
27212721
return %retval : $()
27222722
}
2723+
27232724
// CHECK-LABEL: sil [ossa] @test_yield_1_two_values : {{.*}} {
27242725
// CHECK: tuple_element_addr
27252726
// CHECK: tuple_element_addr
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %target-sil-opt -address-lowering -enable-sil-opaque-values -emit-sorted-sil -module-name Swift -sil-verify-all %s | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Builtin
6+
7+
typealias AnyObject = Builtin.AnyObject
8+
9+
// The module name must be Swift so that declarations like Error are parsed as the correct loadable type.
10+
11+
struct UnownedBox<T : AnyObject> {
12+
unowned var value: T
13+
}
14+
15+
// CHECK-LABEL: sil [ossa] @test_strong_copy_unowned_value : {{.*}} {
16+
// CHECK: bb0([[INSTANCE_ADDR:%[^,]+]] :
17+
// CHECK: [[FIELD_ADDR:%[^,]+]] = struct_element_addr [[INSTANCE_ADDR]]
18+
// CHECK: [[OWNED_VALUE:%[^,]+]] = load_unowned [[FIELD_ADDR]]
19+
// CHECK: return [[OWNED_VALUE]]
20+
// CHECK-LABEL: } // end sil function 'test_strong_copy_unowned_value'
21+
sil [ossa] @test_strong_copy_unowned_value : $@convention(thin) <T where T : AnyObject> (@in_guaranteed UnownedBox<T>) -> @owned T {
22+
bb0(%instance : @guaranteed $UnownedBox<T>):
23+
%unowned_value = struct_extract %instance : $UnownedBox<T>, #UnownedBox.value
24+
%owned_value = strong_copy_unowned_value %unowned_value : $@sil_unowned T
25+
return %owned_value : $T
26+
}
27+
28+
// CHECK-LABEL: sil [ossa] @test_unowned_copy_value : {{.*}} {
29+
// CHECK: bb0([[INSTANCE_OUT:%[^,]+]] : {{.*}}, [[OWNED_VALUE:%[^,]+]] :
30+
// CHECK: [[FIELD_ADDR:%[^,]+]] = struct_element_addr [[INSTANCE_OUT]]
31+
// CHECK: store_unowned [[OWNED_VALUE]] to [init] [[FIELD_ADDR]]
32+
// CHECK: destroy_value [[OWNED_VALUE]]
33+
// CHECK-LABEL: } // end sil function 'test_unowned_copy_value'
34+
sil [ossa] @test_unowned_copy_value : $@convention(thin) <T where T : AnyObject> (@owned T) -> @out UnownedBox<T> {
35+
bb0(%owned_value : @owned $T):
36+
%unowned_value = unowned_copy_value %owned_value : $T
37+
destroy_value %owned_value : $T
38+
%instance = struct $UnownedBox<T> (%unowned_value : $@sil_unowned T)
39+
return %instance : $UnownedBox<T>
40+
}

0 commit comments

Comments
 (0)