Skip to content

Commit 8796dbe

Browse files
authored
Merge pull request #63896 from jckarter/moveonly-value-witness-bits
IRGen: Reuse "POD" to mean "trivially destroyable", and add a "Copyable" bit.
2 parents a3bb205 + f8e3e40 commit 8796dbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+809
-352
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: 9 additions & 5 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, IsPOD_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, IsPOD_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());
@@ -90,7 +94,7 @@ class FixedTypeInfo : public TypeInfo {
9094
llvm::Value *getSize(IRGenFunction &IGF, SILType T) const override;
9195
llvm::Value *getAlignmentMask(IRGenFunction &IGF, SILType T) const override;
9296
llvm::Value *getStride(IRGenFunction &IGF, SILType T) const override;
93-
llvm::Value *getIsPOD(IRGenFunction &IGF, SILType T) const override;
97+
llvm::Value *getIsTriviallyDestroyable(IRGenFunction &IGF, SILType T) const override;
9498
llvm::Value *getIsBitwiseTakable(IRGenFunction &IGF, SILType T) const override;
9599
llvm::Value *isDynamicallyPackedInline(IRGenFunction &IGF,
96100
SILType T) const override;

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/GenBuiltin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
173173
(void)args.claimAll();
174174
auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
175175
substitutions.getReplacementTypes()[0]);
176-
out.add(valueTy.second.getIsPOD(IGF, valueTy.first));
176+
out.add(valueTy.second.getIsTriviallyDestroyable(IGF, valueTy.first));
177177
return;
178178
}
179179

lib/IRGen/GenConcurrency.cpp

Lines changed: 3 additions & 2 deletions
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, IsPOD, IsFixedSize) {}
46+
align, IsTriviallyDestroyable,
47+
IsCopyable, IsFixedSize) {}
4748

4849
static Size getFirstElementSize(IRGenModule &IGM) {
4950
return IGM.getPointerSize();
@@ -60,7 +61,7 @@ class ExecutorTypeInfo :
6061
return IGM.typeLayoutCache.getOrCreateTypeInfoBasedEntry(*this, T);
6162
}
6263
return IGM.typeLayoutCache.getOrCreateScalarEntry(*this, T,
63-
ScalarKind::POD);
64+
ScalarKind::TriviallyDestroyable);
6465
}
6566

6667
static Size getSecondElementOffset(IRGenModule &IGM) {

lib/IRGen/GenDiffFunc.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ class DifferentiableFuncTypeInfo final
9494
DifferentiableFuncTypeInfo(ArrayRef<DifferentiableFuncFieldInfo> fields,
9595
unsigned explosionSize, llvm::Type *ty, Size size,
9696
SpareBitVector &&spareBits, Alignment align,
97-
IsPOD_t isPOD, IsFixedSize_t alwaysFixedSize)
97+
IsTriviallyDestroyable_t isTriviallyDestroyable, IsFixedSize_t alwaysFixedSize)
9898
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
99-
isPOD, alwaysFixedSize) {}
99+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
100100

101101
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
102102
const DifferentiableFuncFieldInfo &field) const {
@@ -179,7 +179,7 @@ class DifferentiableFuncTypeBuilder
179179
StructLayout &&layout, unsigned explosionSize) {
180180
return DifferentiableFuncTypeInfo::create(
181181
fields, explosionSize, layout.getType(), layout.getSize(),
182-
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isPOD(),
182+
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isTriviallyDestroyable(),
183183
layout.isAlwaysFixedSize());
184184
}
185185

@@ -267,10 +267,10 @@ class LinearFuncTypeInfo final
267267
public:
268268
LinearFuncTypeInfo(ArrayRef<LinearFuncFieldInfo> fields,
269269
unsigned explosionSize, llvm::Type *ty, Size size,
270-
SpareBitVector &&spareBits, Alignment align, IsPOD_t isPOD,
270+
SpareBitVector &&spareBits, Alignment align, IsTriviallyDestroyable_t isTriviallyDestroyable,
271271
IsFixedSize_t alwaysFixedSize)
272272
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
273-
isPOD, alwaysFixedSize) {}
273+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
274274

275275
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
276276
const LinearFuncFieldInfo &field) const {
@@ -347,7 +347,7 @@ class LinearFuncTypeBuilder
347347
unsigned explosionSize) {
348348
return LinearFuncTypeInfo::create(
349349
fields, explosionSize, layout.getType(), layout.getSize(),
350-
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isPOD(),
350+
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isTriviallyDestroyable(),
351351
layout.isAlwaysFixedSize());
352352
}
353353

0 commit comments

Comments
 (0)