Skip to content

Commit a5050f5

Browse files
committed
[IRGen] Make address-only existential reference storage types model optionality
1 parent 8231b3a commit a5050f5

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

lib/IRGen/GenExistential.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ namespace {
247247

248248
using super::asDerived;
249249
using super::emitCopyOfTables;
250-
using super::getNumStoredProtocols;
251250

252251
protected:
252+
using super::getNumStoredProtocols;
253253
const ReferenceCounting Refcounting;
254254

255255
template <class... As>
@@ -618,13 +618,13 @@ namespace {
618618
};
619619

620620
/// A type implementation for existential types.
621-
#define LOADABLE_REF_STORAGE_HELPER(Name) \
621+
#define REF_STORAGE_HELPER(Name, Super) \
622622
private: \
623623
bool shouldStoreExtraInhabitantsInRef(IRGenModule &IGM) const { \
624-
if (getNumStoredProtocols() == 0) \
624+
if (IGM.getReferenceStorageExtraInhabitantCount( \
625+
ReferenceOwnership::Name, Refcounting) > 1) \
625626
return true; \
626-
return IGM.getReferenceStorageExtraInhabitantCount( \
627-
ReferenceOwnership::Name, Refcounting) > 1; \
627+
return getNumStoredProtocols() == 0; \
628628
} \
629629
public: \
630630
bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { \
@@ -635,7 +635,7 @@ namespace {
635635
return IGM.getReferenceStorageExtraInhabitantCount( \
636636
ReferenceOwnership::Name, Refcounting) - IsOptional; \
637637
} else { \
638-
return LoadableTypeInfo::getFixedExtraInhabitantCount(IGM); \
638+
return Super::getFixedExtraInhabitantCount(IGM); \
639639
} \
640640
} \
641641
APInt getFixedExtraInhabitantValue(IRGenModule &IGM, \
@@ -647,8 +647,7 @@ namespace {
647647
ReferenceOwnership::Name, \
648648
Refcounting); \
649649
} else { \
650-
return LoadableTypeInfo::getFixedExtraInhabitantValue(IGM, \
651-
bits, index); \
650+
return Super::getFixedExtraInhabitantValue(IGM, bits, index); \
652651
} \
653652
} \
654653
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
@@ -658,7 +657,7 @@ namespace {
658657
return IGF.getReferenceStorageExtraInhabitantIndex(valueSrc, \
659658
ReferenceOwnership::Name, Refcounting); \
660659
} else { \
661-
return LoadableTypeInfo::getExtraInhabitantIndex(IGF, src, T); \
660+
return Super::getExtraInhabitantIndex(IGF, src, T); \
662661
} \
663662
} \
664663
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
@@ -668,7 +667,7 @@ namespace {
668667
return IGF.storeReferenceStorageExtraInhabitant(index, valueDest, \
669668
ReferenceOwnership::Name, Refcounting); \
670669
} else { \
671-
return LoadableTypeInfo::storeExtraInhabitant(IGF, index, dest, T); \
670+
return Super::storeExtraInhabitant(IGF, index, dest, T); \
672671
} \
673672
} \
674673
APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { \
@@ -680,14 +679,15 @@ namespace {
680679
bits = bits.zextOrTrunc(getFixedSize().getValueInBits()); \
681680
return bits; \
682681
} else { \
683-
return LoadableTypeInfo::getFixedExtraInhabitantMask(IGM); \
682+
return Super::getFixedExtraInhabitantMask(IGM); \
684683
} \
685684
}
686685
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
687686
class AddressOnly##Name##ClassExistentialTypeInfo final : \
688687
public AddressOnlyClassExistentialTypeInfoBase< \
689688
AddressOnly##Name##ClassExistentialTypeInfo, \
690689
FixedTypeInfo> { \
690+
bool IsOptional; \
691691
public: \
692692
AddressOnly##Name##ClassExistentialTypeInfo( \
693693
ArrayRef<ProtocolEntry> protocols, \
@@ -700,7 +700,8 @@ namespace {
700700
ty, size, std::move(spareBits), \
701701
align, IsNotPOD, \
702702
IsNotBitwiseTakable, \
703-
IsFixedSize) {} \
703+
IsFixedSize), \
704+
IsOptional(isOptional) {} \
704705
void emitValueAssignWithCopy(IRGenFunction &IGF, \
705706
Address dest, Address src) const { \
706707
IGF.emit##Name##CopyAssign(dest, src, Refcounting); \
@@ -721,6 +722,7 @@ namespace {
721722
IGF.emit##Name##Destroy(addr, Refcounting); \
722723
} \
723724
StringRef getStructNameSuffix() const { return "." #name "ref"; } \
725+
REF_STORAGE_HELPER(Name, FixedTypeInfo) \
724726
};
725727
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
726728
class Loadable##Name##ClassExistentialTypeInfo final \
@@ -767,7 +769,7 @@ namespace {
767769
getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const { \
768770
llvm_unreachable("should have overridden all actual uses of this"); \
769771
} \
770-
LOADABLE_REF_STORAGE_HELPER(Name) \
772+
REF_STORAGE_HELPER(Name, LoadableTypeInfo) \
771773
};
772774
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
773775
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...") \
@@ -794,16 +796,16 @@ namespace {
794796
else \
795797
return IGM.getUnknownObjectTypeInfo(); \
796798
} \
797-
/* FIXME -- Use LOADABLE_REF_STORAGE_HELPER and make */ \
798-
/* getValueTypeInfoForExtraInhabitantsThis call llvm_unreachable() */ \
799+
/* FIXME -- Use REF_STORAGE_HELPER and make */ \
800+
/* getValueTypeInfoForExtraInhabitants call llvm_unreachable() */ \
799801
void emitValueRetain(IRGenFunction &IGF, llvm::Value *value, \
800802
Atomicity atomicity) const {} \
801803
void emitValueRelease(IRGenFunction &IGF, llvm::Value *value, \
802804
Atomicity atomicity) const {} \
803805
void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const {} \
804806
};
805807
#include "swift/AST/ReferenceStorage.def"
806-
#undef LOADABLE_REF_STORAGE_HELPER
808+
#undef REF_STORAGE_HELPER
807809
} // end anonymous namespace
808810

809811

test/IRGen/type_layout_reference_storage.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ struct ReferenceStorageTypeLayout<T, Native : C, Unknown : AnyObject> {
9797
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_4_4_[[REF_XI]]_pod, i32 0, i32 0)
9898
unowned(unsafe) var aou: AnyObject
9999
// CHECK-native-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_8_[[REF_XI]]_bt, i32 0, i32 0)
100-
// CHECK-objc-64: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_8_8_0, i32 0, i32 0)
100+
// CHECK-objc-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_8_1, i32 0, i32 0)
101101
// CHECK-native-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_4_4_[[REF_XI]]_bt, i32 0, i32 0)
102-
// CHECK-objc-32: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_4_4_0, i32 0, i32 0)
102+
// CHECK-objc-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_4_4_1, i32 0, i32 0)
103103
unowned(safe) var aos: AnyObject
104104
// CHECK-64: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_8_8_0, i32 0, i32 0)
105105
// CHECK-32: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_4_4_0, i32 0, i32 0)

0 commit comments

Comments
 (0)