Skip to content

Commit ded4d32

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 57c7c9e commit ded4d32

File tree

4 files changed

+65
-13
lines changed

4 files changed

+65
-13
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
@@ -4847,8 +4847,11 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
48474847
B.emitDestroyValueOperation(loc, semanticValue);
48484848
return value;
48494849
}
4850-
case ReferenceOwnership::Unowned:
4851-
llvm_unreachable("unimplemented");
4850+
case ReferenceOwnership::Unowned: {
4851+
auto value = B.createUnownedCopyValue(loc, semanticValue);
4852+
B.emitDestroyValueOperation(loc, semanticValue);
4853+
return value;
4854+
}
48524855
}
48534856
}
48544857
switch (swiftStorageType->getOwnership()) {
@@ -4864,16 +4867,16 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
48644867
B.emitDestroyValueOperation(loc, semanticValue); \
48654868
return value; \
48664869
}
4867-
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4868-
case ReferenceOwnership::Name: { \
4869-
/* For loadable types, place into a box. */ \
4870-
auto type = storageType.castTo<Name##StorageType>(); \
4871-
assert(type->isLoadable(ResilienceExpansion::Maximal)); \
4872-
(void) type; \
4873-
SILValue value = B.createRefTo##Name(loc, semanticValue, storageType); \
4874-
value = B.createCopyValue(loc, value); \
4875-
B.emitDestroyValueOperation(loc, semanticValue); \
4876-
return value; \
4870+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4871+
case ReferenceOwnership::Name: { \
4872+
/* For loadable types, place into a box. */ \
4873+
auto type = storageType.castTo<Name##StorageType>(); \
4874+
assert(type->isLoadable(ResilienceExpansion::Maximal)); \
4875+
(void)type; \
4876+
SILValue value = B.createRefTo##Name(loc, semanticValue, storageType); \
4877+
value = B.createCopyValue(loc, value); \
4878+
B.emitDestroyValueOperation(loc, semanticValue); \
4879+
return value; \
48774880
}
48784881
#define UNCHECKED_REF_STORAGE(Name, ...) \
48794882
case ReferenceOwnership::Name: { \
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)