Skip to content

IRGen: Reuse "POD" to mean "trivially destroyable", and add a "Copyable" bit. #63896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ class TargetValueWitnessFlags {
IsNonBitwiseTakable = 0x00100000,
HasEnumWitnesses = 0x00200000,
Incomplete = 0x00400000,
// unused 0xFF800000,
IsNonCopyable = 0x00800000,
// unused 0xFF000000,
};

static constexpr const uint32_t MaxNumExtraInhabitants = 0x7FFFFFFF;
Expand Down Expand Up @@ -209,8 +210,8 @@ class TargetValueWitnessFlags {
(isInline ? 0 : IsNonInline));
}

/// True if values of this type can be copied with memcpy and
/// destroyed with a no-op.
/// True if values of this type can be copied with memcpy (if it's copyable)
/// and destroyed with a no-op.
bool isPOD() const { return !(Data & IsNonPOD); }
constexpr TargetValueWitnessFlags withPOD(bool isPOD) const {
return TargetValueWitnessFlags((Data & ~IsNonPOD) |
Expand All @@ -227,6 +228,13 @@ class TargetValueWitnessFlags {
return TargetValueWitnessFlags((Data & ~IsNonBitwiseTakable) |
(isBT ? 0 : IsNonBitwiseTakable));
}

/// True if values of this type can be copied.
bool isCopyable() const { return !(Data & IsNonCopyable); }
constexpr TargetValueWitnessFlags withCopyable(bool isCopyable) const {
return TargetValueWitnessFlags((Data & ~IsNonCopyable) |
(isCopyable ? 0 : IsNonCopyable));
}

/// True if this type's binary representation is that of an enum, and the
/// enum value witness table entries are available in this type's value
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4011,6 +4011,10 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
bool isGlobalActor() const {
return getGlobalActorInstance() != nullptr;
}

/// Return the `DestructorDecl` for a struct or enum's `deinit` declaration.
/// Returns null if the type is a class, or does not have a declared `deinit`.
DestructorDecl *getValueTypeDestructor();

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
Expand Down
12 changes: 12 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4578,6 +4578,18 @@ bool NominalTypeDecl::isResilient() const {
return getModuleContext()->isResilient();
}

DestructorDecl *NominalTypeDecl::getValueTypeDestructor() {
if (!isa<StructDecl>(this) && !isa<EnumDecl>(this)) {
return nullptr;
}

auto found = lookupDirect(DeclBaseName::createDestructor());
if (found.size() != 1) {
return nullptr;
}
return cast<DestructorDecl>(found[0]);
}

static bool isOriginallyDefinedIn(const Decl *D, const ModuleDecl* MD) {
if (!MD)
return false;
Expand Down
14 changes: 9 additions & 5 deletions lib/IRGen/FixedTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ class FixedTypeInfo : public TypeInfo {
protected:
FixedTypeInfo(llvm::Type *type, Size size,
const SpareBitVector &spareBits,
Alignment align, IsPOD_t pod, IsBitwiseTakable_t bt,
Alignment align, IsTriviallyDestroyable_t pod,
IsBitwiseTakable_t bt,
IsCopyable_t copy,
IsFixedSize_t alwaysFixedSize,
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
: TypeInfo(type, align, pod, bt, alwaysFixedSize, IsABIAccessible, stik),
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
SpareBits(spareBits) {
assert(SpareBits.size() == size.getValueInBits());
assert(isFixedSize());
Expand All @@ -55,10 +57,12 @@ class FixedTypeInfo : public TypeInfo {

FixedTypeInfo(llvm::Type *type, Size size,
SpareBitVector &&spareBits,
Alignment align, IsPOD_t pod, IsBitwiseTakable_t bt,
Alignment align, IsTriviallyDestroyable_t pod,
IsBitwiseTakable_t bt,
IsCopyable_t copy,
IsFixedSize_t alwaysFixedSize,
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
: TypeInfo(type, align, pod, bt, alwaysFixedSize, IsABIAccessible, stik),
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
SpareBits(std::move(spareBits)) {
assert(SpareBits.size() == size.getValueInBits());
assert(isFixedSize());
Expand Down Expand Up @@ -90,7 +94,7 @@ class FixedTypeInfo : public TypeInfo {
llvm::Value *getSize(IRGenFunction &IGF, SILType T) const override;
llvm::Value *getAlignmentMask(IRGenFunction &IGF, SILType T) const override;
llvm::Value *getStride(IRGenFunction &IGF, SILType T) const override;
llvm::Value *getIsPOD(IRGenFunction &IGF, SILType T) const override;
llvm::Value *getIsTriviallyDestroyable(IRGenFunction &IGF, SILType T) const override;
llvm::Value *getIsBitwiseTakable(IRGenFunction &IGF, SILType T) const override;
llvm::Value *isDynamicallyPackedInline(IRGenFunction &IGF,
SILType T) const override;
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenArchetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class OpaqueArchetypeTypeInfo
: public ResilientTypeInfo<OpaqueArchetypeTypeInfo>
{
OpaqueArchetypeTypeInfo(llvm::Type *type, IsABIAccessible_t abiAccessible)
: ResilientTypeInfo(type, abiAccessible) {}
: ResilientTypeInfo(type, IsCopyable, abiAccessible) {}

public:
static const OpaqueArchetypeTypeInfo *
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
(void)args.claimAll();
auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
substitutions.getReplacementTypes()[0]);
out.add(valueTy.second.getIsPOD(IGF, valueTy.first));
out.add(valueTy.second.getIsTriviallyDestroyable(IGF, valueTy.first));
return;
}

Expand Down
5 changes: 3 additions & 2 deletions lib/IRGen/GenConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class ExecutorTypeInfo :
ExecutorTypeInfo(llvm::StructType *storageType,
Size size, Alignment align, SpareBitVector &&spareBits)
: TrivialScalarPairTypeInfo(storageType, size, std::move(spareBits),
align, IsPOD, IsFixedSize) {}
align, IsTriviallyDestroyable,
IsCopyable, IsFixedSize) {}

static Size getFirstElementSize(IRGenModule &IGM) {
return IGM.getPointerSize();
Expand All @@ -60,7 +61,7 @@ class ExecutorTypeInfo :
return IGM.typeLayoutCache.getOrCreateTypeInfoBasedEntry(*this, T);
}
return IGM.typeLayoutCache.getOrCreateScalarEntry(*this, T,
ScalarKind::POD);
ScalarKind::TriviallyDestroyable);
}

static Size getSecondElementOffset(IRGenModule &IGM) {
Expand Down
12 changes: 6 additions & 6 deletions lib/IRGen/GenDiffFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ class DifferentiableFuncTypeInfo final
DifferentiableFuncTypeInfo(ArrayRef<DifferentiableFuncFieldInfo> fields,
unsigned explosionSize, llvm::Type *ty, Size size,
SpareBitVector &&spareBits, Alignment align,
IsPOD_t isPOD, IsFixedSize_t alwaysFixedSize)
IsTriviallyDestroyable_t isTriviallyDestroyable, IsFixedSize_t alwaysFixedSize)
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
isPOD, alwaysFixedSize) {}
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}

Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
const DifferentiableFuncFieldInfo &field) const {
Expand Down Expand Up @@ -179,7 +179,7 @@ class DifferentiableFuncTypeBuilder
StructLayout &&layout, unsigned explosionSize) {
return DifferentiableFuncTypeInfo::create(
fields, explosionSize, layout.getType(), layout.getSize(),
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isPOD(),
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isTriviallyDestroyable(),
layout.isAlwaysFixedSize());
}

Expand Down Expand Up @@ -267,10 +267,10 @@ class LinearFuncTypeInfo final
public:
LinearFuncTypeInfo(ArrayRef<LinearFuncFieldInfo> fields,
unsigned explosionSize, llvm::Type *ty, Size size,
SpareBitVector &&spareBits, Alignment align, IsPOD_t isPOD,
SpareBitVector &&spareBits, Alignment align, IsTriviallyDestroyable_t isTriviallyDestroyable,
IsFixedSize_t alwaysFixedSize)
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
isPOD, alwaysFixedSize) {}
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}

Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
const LinearFuncFieldInfo &field) const {
Expand Down Expand Up @@ -347,7 +347,7 @@ class LinearFuncTypeBuilder
unsigned explosionSize) {
return LinearFuncTypeInfo::create(
fields, explosionSize, layout.getType(), layout.getSize(),
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isPOD(),
std::move(layout.getSpareBits()), layout.getAlignment(), layout.isTriviallyDestroyable(),
layout.isAlwaysFixedSize());
}

Expand Down
Loading