Skip to content

Commit 03a2393

Browse files
committed
IRGen: Track IsCopyable through type infos.
And use the new bit to ensure we don't try to lower move-only types with common layout value witness surrogates. Take a bit in the runtime value witness flags to represent types that are not copyable.
1 parent a572c3f commit 03a2393

29 files changed

+393
-109
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ class TargetValueWitnessFlags {
163163
IsNonBitwiseTakable = 0x00100000,
164164
HasEnumWitnesses = 0x00200000,
165165
Incomplete = 0x00400000,
166-
// unused 0xFF800000,
166+
IsNonCopyable = 0x00800000,
167+
// unused 0xFF000000,
167168
};
168169

169170
static constexpr const uint32_t MaxNumExtraInhabitants = 0x7FFFFFFF;
@@ -209,8 +210,8 @@ class TargetValueWitnessFlags {
209210
(isInline ? 0 : IsNonInline));
210211
}
211212

212-
/// True if values of this type can be copied with memcpy and
213-
/// destroyed with a no-op.
213+
/// True if values of this type can be copied with memcpy (if it's copyable)
214+
/// and destroyed with a no-op.
214215
bool isPOD() const { return !(Data & IsNonPOD); }
215216
constexpr TargetValueWitnessFlags withPOD(bool isPOD) const {
216217
return TargetValueWitnessFlags((Data & ~IsNonPOD) |
@@ -227,6 +228,13 @@ class TargetValueWitnessFlags {
227228
return TargetValueWitnessFlags((Data & ~IsNonBitwiseTakable) |
228229
(isBT ? 0 : IsNonBitwiseTakable));
229230
}
231+
232+
/// True if values of this type can be copied.
233+
bool isCopyable() const { return !(Data & IsNonCopyable); }
234+
constexpr TargetValueWitnessFlags withCopyable(bool isCopyable) const {
235+
return TargetValueWitnessFlags((Data & ~IsNonCopyable) |
236+
(isCopyable ? 0 : IsNonCopyable));
237+
}
230238

231239
/// True if this type's binary representation is that of an enum, and the
232240
/// enum value witness table entries are available in this type's value

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4011,6 +4011,10 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
40114011
bool isGlobalActor() const {
40124012
return getGlobalActorInstance() != nullptr;
40134013
}
4014+
4015+
/// Return the `DestructorDecl` for a struct or enum's `deinit` declaration.
4016+
/// Returns null if the type is a class, or does not have a declared `deinit`.
4017+
DestructorDecl *getValueTypeDestructor();
40144018

40154019
// Implement isa/cast/dyncast/etc.
40164020
static bool classof(const Decl *D) {

lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4578,6 +4578,18 @@ bool NominalTypeDecl::isResilient() const {
45784578
return getModuleContext()->isResilient();
45794579
}
45804580

4581+
DestructorDecl *NominalTypeDecl::getValueTypeDestructor() {
4582+
if (!isa<StructDecl>(this) && !isa<EnumDecl>(this)) {
4583+
return nullptr;
4584+
}
4585+
4586+
auto found = lookupDirect(DeclBaseName::createDestructor());
4587+
if (found.size() != 1) {
4588+
return nullptr;
4589+
}
4590+
return cast<DestructorDecl>(found[0]);
4591+
}
4592+
45814593
static bool isOriginallyDefinedIn(const Decl *D, const ModuleDecl* MD) {
45824594
if (!MD)
45834595
return false;

lib/IRGen/FixedTypeInfo.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ class FixedTypeInfo : public TypeInfo {
4242
protected:
4343
FixedTypeInfo(llvm::Type *type, Size size,
4444
const SpareBitVector &spareBits,
45-
Alignment align, IsTriviallyDestroyable_t pod, IsBitwiseTakable_t bt,
45+
Alignment align, IsTriviallyDestroyable_t pod,
46+
IsBitwiseTakable_t bt,
47+
IsCopyable_t copy,
4648
IsFixedSize_t alwaysFixedSize,
4749
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
48-
: TypeInfo(type, align, pod, bt, alwaysFixedSize, IsABIAccessible, stik),
50+
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
4951
SpareBits(spareBits) {
5052
assert(SpareBits.size() == size.getValueInBits());
5153
assert(isFixedSize());
@@ -55,10 +57,12 @@ class FixedTypeInfo : public TypeInfo {
5557

5658
FixedTypeInfo(llvm::Type *type, Size size,
5759
SpareBitVector &&spareBits,
58-
Alignment align, IsTriviallyDestroyable_t pod, IsBitwiseTakable_t bt,
60+
Alignment align, IsTriviallyDestroyable_t pod,
61+
IsBitwiseTakable_t bt,
62+
IsCopyable_t copy,
5963
IsFixedSize_t alwaysFixedSize,
6064
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
61-
: TypeInfo(type, align, pod, bt, alwaysFixedSize, IsABIAccessible, stik),
65+
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
6266
SpareBits(std::move(spareBits)) {
6367
assert(SpareBits.size() == size.getValueInBits());
6468
assert(isFixedSize());

lib/IRGen/GenArchetype.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class OpaqueArchetypeTypeInfo
102102
: public ResilientTypeInfo<OpaqueArchetypeTypeInfo>
103103
{
104104
OpaqueArchetypeTypeInfo(llvm::Type *type, IsABIAccessible_t abiAccessible)
105-
: ResilientTypeInfo(type, abiAccessible) {}
105+
: ResilientTypeInfo(type, IsCopyable, abiAccessible) {}
106106

107107
public:
108108
static const OpaqueArchetypeTypeInfo *

lib/IRGen/GenConcurrency.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class ExecutorTypeInfo :
4343
ExecutorTypeInfo(llvm::StructType *storageType,
4444
Size size, Alignment align, SpareBitVector &&spareBits)
4545
: TrivialScalarPairTypeInfo(storageType, size, std::move(spareBits),
46-
align, IsTriviallyDestroyable, IsFixedSize) {}
46+
align, IsTriviallyDestroyable,
47+
IsCopyable, IsFixedSize) {}
4748

4849
static Size getFirstElementSize(IRGenModule &IGM) {
4950
return IGM.getPointerSize();

lib/IRGen/GenDiffFunc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class DifferentiableFuncTypeInfo final
9696
SpareBitVector &&spareBits, Alignment align,
9797
IsTriviallyDestroyable_t isTriviallyDestroyable, IsFixedSize_t alwaysFixedSize)
9898
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
99-
isTriviallyDestroyable, alwaysFixedSize) {}
99+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
100100

101101
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
102102
const DifferentiableFuncFieldInfo &field) const {
@@ -270,7 +270,7 @@ class LinearFuncTypeInfo final
270270
SpareBitVector &&spareBits, Alignment align, IsTriviallyDestroyable_t isTriviallyDestroyable,
271271
IsFixedSize_t alwaysFixedSize)
272272
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
273-
isTriviallyDestroyable, alwaysFixedSize) {}
273+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
274274

275275
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
276276
const LinearFuncFieldInfo &field) const {

0 commit comments

Comments
 (0)