Skip to content

Commit b00ccb1

Browse files
committed
[OpaqueValues] Emit unowned copies.
In opaque values mode, emit the unowned copy instructions to convert as follows: strong_copy_unowned_value: `@owned $sil_unowned T` -> `@owned $T` unowned_copy_value: `@owned T` -> `@owned $sil_unowned T` Doing so is necessary in opaque values mode where it is needed to deal with unowned values directly rather than indirectly via `load_unowned`s and `store_unowned`s.
1 parent 8b82c4e commit b00ccb1

File tree

5 files changed

+66
-14
lines changed

5 files changed

+66
-14
lines changed

lib/SILGen/SILGenBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ ManagedValue SILGenBuilder::createCopyValue(SILLocation loc,
191191
ManagedValue SILGenBuilder::createStrongCopy##Name##Value( \
192192
SILLocation loc, ManagedValue originalValue) { \
193193
auto ty = originalValue.getType().castTo<Name##StorageType>(); \
194-
assert(ty->isLoadable(ResilienceExpansion::Maximal)); \
194+
assert(ty->isLoadable(ResilienceExpansion::Maximal) || \
195+
!SGF.useLoweredAddresses()); \
195196
(void)ty; \
196197
SILValue result = \
197198
createStrongCopy##Name##Value(loc, originalValue.getValue()); \

lib/SILGen/SILGenLValue.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4717,8 +4717,11 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
47174717
B.emitDestroyValueOperation(loc, semanticValue);
47184718
return value;
47194719
}
4720-
case ReferenceOwnership::Unowned:
4721-
llvm_unreachable("unimplemented");
4720+
case ReferenceOwnership::Unowned: {
4721+
auto value = B.createUnownedCopyValue(loc, semanticValue);
4722+
B.emitDestroyValueOperation(loc, semanticValue);
4723+
return value;
4724+
}
47224725
}
47234726
}
47244727
switch (swiftStorageType->getOwnership()) {
@@ -4734,16 +4737,16 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
47344737
B.emitDestroyValueOperation(loc, semanticValue); \
47354738
return value; \
47364739
}
4737-
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4738-
case ReferenceOwnership::Name: { \
4739-
/* For loadable types, place into a box. */ \
4740-
auto type = storageType.castTo<Name##StorageType>(); \
4741-
assert(type->isLoadable(ResilienceExpansion::Maximal)); \
4742-
(void) type; \
4743-
SILValue value = B.createRefTo##Name(loc, semanticValue, storageType); \
4744-
value = B.createCopyValue(loc, value); \
4745-
B.emitDestroyValueOperation(loc, semanticValue); \
4746-
return value; \
4740+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4741+
case ReferenceOwnership::Name: { \
4742+
/* For loadable types, place into a box. */ \
4743+
auto type = storageType.castTo<Name##StorageType>(); \
4744+
assert(type->isLoadable(ResilienceExpansion::Maximal)); \
4745+
(void)type; \
4746+
SILValue value = B.createRefTo##Name(loc, semanticValue, storageType); \
4747+
value = B.createCopyValue(loc, value); \
4748+
B.emitDestroyValueOperation(loc, semanticValue); \
4749+
return value; \
47474750
}
47484751
#define UNCHECKED_REF_STORAGE(Name, ...) \
47494752
case ReferenceOwnership::Name: { \

test/SILGen/opaque_values_silgen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
1+
// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
22

33
// Test SILGen -enable-sil-opaque-values with tests that depend on the stdlib.
44

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -disable-objc-interop -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
2+
3+
// Test SILGen -enable-sil-opaque-values with tests that depend on the stdlib and objc interop.
4+
5+
// REQUIRES: objc_interop
6+
7+
// CHECK-LABEL: sil {{.*}}[ossa] @$s28opaque_values_silgen_nonobjc13UnownedVarBoxV5valuexvg : {{.*}} {
8+
// CHECK: bb0([[INSTANCE:%[^,]+]] :
9+
// CHECK: [[UNOWNED_VALUE:%[^,]+]] = struct_extract [[INSTANCE]]
10+
// CHECK: [[STRONG_VALUE:%[^,]+]] = strong_copy_unowned_value [[UNOWNED_VALUE]]
11+
// CHECK: return [[STRONG_VALUE]]
12+
// CHECK-LABEL: } // end sil function '$s28opaque_values_silgen_nonobjc13UnownedVarBoxV5valuexvg'
13+
// CHECK-LABEL: sil {{.*}}[ossa] @$s28opaque_values_silgen_nonobjc13UnownedVarBoxV5valueACyxGx_tcfC : {{.*}} {
14+
// CHECK: bb0([[STRONG_VALUE:%[^,]+]] :
15+
// CHECK: [[WRAPPED_IN_UNOWNED_TYPE:%[^,]+]] = ref_to_unowned [[STRONG_VALUE]]
16+
// CHECK: [[UNOWNED_VALUE:%[^,]+]] = copy_value [[WRAPPED_IN_UNOWNED_TYPE]]
17+
// CHECK: destroy_value [[STRONG_VALUE]]
18+
// CHECK: [[RETVAL:%[^,]+]] = struct $UnownedVarBox<T> ([[UNOWNED_VALUE]] : $@sil_unowned T)
19+
// CHECK: return [[RETVAL]]
20+
// CHECK-LABEL: } // end sil function '$s28opaque_values_silgen_nonobjc13UnownedVarBoxV5valueACyxGx_tcfC'
21+
struct UnownedVarBox<T : AnyObject> {
22+
unowned var value: T
23+
}
24+
25+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-emit-silgen -enable-sil-opaque-values -Xllvm -sil-full-demangle -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
2+
3+
// Test SILGen -enable-sil-opaque-values with tests that depend on the stdlib and objc interop.
4+
5+
// REQUIRES: objc_interop
6+
7+
// CHECK-LABEL: sil {{.*}}[ossa] @$s25opaque_values_silgen_objc10UnownedBoxV5valuexvg : {{.*}} {
8+
// CHECK: bb0([[INSTANCE:%[^,]+]] :
9+
// CHECK: [[UNOWNED_VALUE:%[^,]+]] = struct_extract [[INSTANCE]]
10+
// CHECK: [[STRONG_VALUE:%[^,]+]] = strong_copy_unowned_value [[UNOWNED_VALUE]]
11+
// CHECK: return [[STRONG_VALUE]]
12+
// CHECK-LABEL: } // end sil function '$s25opaque_values_silgen_objc10UnownedBoxV5valuexvg'
13+
// CHECK-LABEL: sil {{.*}}[ossa] @$s25opaque_values_silgen_objc10UnownedBoxV5valueACyxGx_tcfC : {{.*}} {
14+
// CHECK: bb0([[STRONG_VALUE:%[^,]+]] :
15+
// CHECK: [[UNOWNED_VALUE:%[^,]+]] = unowned_copy_value [[STRONG_VALUE]]
16+
// CHECK: destroy_value [[STRONG_VALUE]]
17+
// CHECK: [[RETVAL:%[^,]+]] = struct $UnownedBox<T> ([[UNOWNED_VALUE]] : $@sil_unowned T)
18+
// CHECK: return [[RETVAL]]
19+
// CHECK-LABEL: } // end sil function '$s25opaque_values_silgen_objc10UnownedBoxV5valueACyxGx_tcfC'
20+
struct UnownedBox<T : AnyObject> {
21+
unowned var value: T
22+
}
23+

0 commit comments

Comments
 (0)