Skip to content

Commit f94837e

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 004d927 commit f94837e

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4414,9 +4414,18 @@ ManagedValue SILGenFunction::emitConversionToSemanticRValue(
44144414
switch (swiftStorageType->getOwnership()) {
44154415
case ReferenceOwnership::Strong:
44164416
llvm_unreachable("strong reference storage type should be impossible");
4417-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4418-
case ReferenceOwnership::Name: \
4419-
/* Address-only storage types are handled with their underlying type. */ \
4417+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4418+
case ReferenceOwnership::Name: \
4419+
if (!useLoweredAddresses()) { \
4420+
auto refTy = src.getType(); \
4421+
auto ty = refTy.getReferenceStorageReferentType(); \
4422+
assert(ty); \
4423+
assert(ty.getOptionalObjectType()); \
4424+
(void)ty; \
4425+
/* Copy the weak value, opening the @sil_weak box. */ \
4426+
return B.createStrongCopy##Name##Value(loc, src); \
4427+
} \
4428+
/* Address-only storage types are handled with their underlying type. */ \
44204429
llvm_unreachable("address-only pointers are handled elsewhere");
44214430
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
44224431
case ReferenceOwnership::Name: \
@@ -4697,11 +4706,26 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
46974706
}
46984707

46994708
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
4709+
if (!useLoweredAddresses() && storageType.isAddressOnly(F)) {
4710+
switch (swiftStorageType->getOwnership()) {
4711+
case ReferenceOwnership::Strong:
4712+
llvm_unreachable("strong reference storage type should be impossible");
4713+
case ReferenceOwnership::Unmanaged:
4714+
llvm_unreachable("unimplemented");
4715+
case ReferenceOwnership::Weak: {
4716+
auto value = B.createWeakCopyValue(loc, semanticValue);
4717+
B.emitDestroyValueOperation(loc, semanticValue);
4718+
return value;
4719+
}
4720+
case ReferenceOwnership::Unowned:
4721+
llvm_unreachable("unimplemented");
4722+
}
4723+
}
47004724
switch (swiftStorageType->getOwnership()) {
47014725
case ReferenceOwnership::Strong:
47024726
llvm_unreachable("strong reference storage type should be impossible");
4703-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4704-
case ReferenceOwnership::Name: \
4727+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
4728+
case ReferenceOwnership::Name: \
47054729
llvm_unreachable("address-only types are never loadable");
47064730
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
47074731
case ReferenceOwnership::Name: { \

test/SILGen/opaque_values_silgen.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,19 @@ func FormClassKeyPath() {
699699
func getInout(_ i: inout MyInt) -> Int {
700700
return i[keyPath: \MyInt.int]
701701
}
702+
// CHECK-LABEL: sil {{.*}}[ossa] @$s20opaque_values_silgen7WeakBoxV1txSgvg : {{.*}} {
703+
// CHECK: bb0([[INSTANCE:%[^,]+]] :
704+
// CHECK: [[WEAK_OPTIONAL:%[^,]+]] = struct_extract [[INSTANCE]]
705+
// CHECK: [[STRONG_OPTIONAL:%[^,]+]] = strong_copy_weak_value [[WEAK_OPTIONAL]]
706+
// CHECK: return [[STRONG_OPTIONAL]]
707+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen7WeakBoxV1txSgvg'
708+
// CHECK-LABEL: sil {{.*}}[ossa] @$s20opaque_values_silgen7WeakBoxV1tACyxGxSg_tcfC : {{.*}} {
709+
// CHECK: bb0([[STRONG_OPTIONAL:%[^,]+]] :
710+
// CHECK: [[WEAK_OPTIONAL:%[^,]+]] = weak_copy_value [[STRONG_OPTIONAL]]
711+
// CHECK: destroy_value [[STRONG_OPTIONAL]]
712+
// CHECK: [[INSTANCE:%[^,]+]] = struct $WeakBox<T> ([[WEAK_OPTIONAL]] :
713+
// CHECK: return [[INSTANCE]]
714+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen7WeakBoxV1tACyxGxSg_tcfC'
715+
struct WeakBox<T : AnyObject> {
716+
weak var t: T?
717+
}

0 commit comments

Comments
 (0)