Skip to content

Commit b616d14

Browse files
committed
[OpaqueValues] Emit weak copies.
In opaque values mode, emit the new weak copy instructions to convert as follows: strong_copy_weak_value: `@owned $sil_weak T?` -> `@owned $T?` weak_copy_value: `@owned $T?` -> `@owned $@sil_weak T?` Doing so is necessary in opaque values mode where it is needed to deal with weak values directly rather than indirectly via `load_weak`s and `store_weak`s.
1 parent 390d02f commit b616d14

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4544,9 +4544,18 @@ ManagedValue SILGenFunction::emitConversionToSemanticRValue(
45444544
switch (swiftStorageType->getOwnership()) {
45454545
case ReferenceOwnership::Strong:
45464546
llvm_unreachable("strong reference storage type should be impossible");
4547-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4548-
case ReferenceOwnership::Name: \
4549-
/* Address-only storage types are handled with their underlying type. */ \
4547+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4548+
case ReferenceOwnership::Name: \
4549+
if (!useLoweredAddresses()) { \
4550+
auto refTy = src.getType(); \
4551+
auto ty = refTy.getReferenceStorageReferentType(); \
4552+
assert(ty); \
4553+
assert(ty.getOptionalObjectType()); \
4554+
(void)ty; \
4555+
/* Copy the weak value, opening the @sil_weak box. */ \
4556+
return B.createStrongCopy##Name##Value(loc, src); \
4557+
} \
4558+
/* Address-only storage types are handled with their underlying type. */ \
45504559
llvm_unreachable("address-only pointers are handled elsewhere");
45514560
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
45524561
case ReferenceOwnership::Name: \
@@ -4827,11 +4836,26 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
48274836
}
48284837

48294838
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
4839+
if (!useLoweredAddresses() && storageType.isAddressOnly(F)) {
4840+
switch (swiftStorageType->getOwnership()) {
4841+
case ReferenceOwnership::Strong:
4842+
llvm_unreachable("strong reference storage type should be impossible");
4843+
case ReferenceOwnership::Unmanaged:
4844+
llvm_unreachable("unimplemented");
4845+
case ReferenceOwnership::Weak: {
4846+
auto value = B.createWeakCopyValue(loc, semanticValue);
4847+
B.emitDestroyValueOperation(loc, semanticValue);
4848+
return value;
4849+
}
4850+
case ReferenceOwnership::Unowned:
4851+
llvm_unreachable("unimplemented");
4852+
}
4853+
}
48304854
switch (swiftStorageType->getOwnership()) {
48314855
case ReferenceOwnership::Strong:
48324856
llvm_unreachable("strong reference storage type should be impossible");
4833-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4834-
case ReferenceOwnership::Name: \
4857+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4858+
case ReferenceOwnership::Name: \
48354859
llvm_unreachable("address-only types are never loadable");
48364860
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
48374861
case ReferenceOwnership::Name: { \

test/SILGen/opaque_values_silgen.swift

Lines changed: 18 additions & 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

@@ -743,3 +743,20 @@ protocol MutatingFooable {
743743
func callMutatingFooOnInoutExistential(_ i: inout any MutatingFooable) {
744744
i.foo()
745745
}
746+
747+
// CHECK-LABEL: sil {{.*}}[ossa] @$s20opaque_values_silgen7WeakBoxV1txSgvg : {{.*}} {
748+
// CHECK: bb0([[INSTANCE:%[^,]+]] :
749+
// CHECK: [[WEAK_OPTIONAL:%[^,]+]] = struct_extract [[INSTANCE]]
750+
// CHECK: [[STRONG_OPTIONAL:%[^,]+]] = strong_copy_weak_value [[WEAK_OPTIONAL]]
751+
// CHECK: return [[STRONG_OPTIONAL]]
752+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen7WeakBoxV1txSgvg'
753+
// CHECK-LABEL: sil {{.*}}[ossa] @$s20opaque_values_silgen7WeakBoxV1tACyxGxSg_tcfC : {{.*}} {
754+
// CHECK: bb0([[STRONG_OPTIONAL:%[^,]+]] :
755+
// CHECK: [[WEAK_OPTIONAL:%[^,]+]] = weak_copy_value [[STRONG_OPTIONAL]]
756+
// CHECK: destroy_value [[STRONG_OPTIONAL]]
757+
// CHECK: [[INSTANCE:%[^,]+]] = struct $WeakBox<T> ([[WEAK_OPTIONAL]] :
758+
// CHECK: return [[INSTANCE]]
759+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen7WeakBoxV1tACyxGxSg_tcfC'
760+
struct WeakBox<T : AnyObject> {
761+
weak var t: T?
762+
}

0 commit comments

Comments
 (0)