llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> We only ever need one of them. Also reorder the Descriptor members a bit to reduce the size of `Desciptor` from 72 to 64 bytes. --- Patch is 27.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217324.diff 11 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-5) - (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+54-52) - (modified) clang/lib/AST/ByteCode/Descriptor.h (+30-17) - (modified) clang/lib/AST/ByteCode/Disasm.cpp (+6-6) - (modified) clang/lib/AST/ByteCode/EvaluationResult.cpp (+6-6) - (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4) - (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-4) - (modified) clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp (+1-1) - (modified) clang/lib/AST/ByteCode/Pointer.cpp (+1-1) - (modified) clang/lib/AST/ByteCode/Pointer.h (+7-5) - (modified) clang/lib/AST/ByteCode/Program.cpp (+1-1) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index cbfd067bfbdd4..9c6fdc70e9300 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5087,7 +5087,7 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R, if (!this->visitZeroArrayInitializer(D->getType(), E)) return false; } else if (D->isRecord()) { - if (!this->visitZeroRecordInitializer(D->ElemRecord, E)) + if (!this->visitZeroRecordInitializer(D->getElemRecord(), E)) return false; } else return false; @@ -8676,7 +8676,7 @@ bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc, // Arrays. if (Desc->isArray()) { - const Descriptor *ElemDesc = Desc->ElemDesc; + const Descriptor *ElemDesc = Desc->getElemDesc(); assert(ElemDesc); unsigned N = Desc->getNumElems(); @@ -8699,9 +8699,9 @@ bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc, return this->emitDestructionPop(ElemDesc, Loc); } - assert(Desc->ElemRecord); - assert(!Desc->ElemRecord->hasTrivialDtor()); - return this->emitRecordDestructionPop(Desc->ElemRecord, Loc); + assert(Desc->isRecord()); + assert(!Desc->getElemRecord()->hasTrivialDtor()); + return this->emitRecordDestructionPop(Desc->getElemRecord(), Loc); } /// Create a dummy pointer for the given decl (or expr) and diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index d0435d4684875..be5d42967059f 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -83,13 +83,13 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, bool InUnion, const Descriptor *D) { const unsigned NumElems = D->getNumElems(); const unsigned ElemSize = - D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor); + D->getElemDesc()->getAllocSize() + sizeof(InlineDescriptor); unsigned ElemOffset = 0; for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) { auto *ElemPtr = Ptr + ElemOffset; auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr); - auto *SD = D->ElemDesc; + auto *SD = D->getElemDesc(); Desc->Offset = ElemOffset + sizeof(InlineDescriptor); Desc->Desc = SD; @@ -102,10 +102,10 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, Desc->IsArrayElement = true; Desc->IsVolatile = IsVolatile; - if (auto Fn = D->ElemDesc->CtorFn) { + if (auto Fn = D->getElemDesc()->CtorFn) { auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1); Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsVolatile, IsActive, - Desc->InUnion || SD->isUnion(), D->ElemDesc); + Desc->InUnion || SD->isUnion(), D->getElemDesc()); } } } @@ -113,17 +113,17 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, static void dtorArrayDesc(Block *B, std::byte *Ptr, const Descriptor *D) { const unsigned NumElems = D->getNumElems(); const unsigned ElemSize = - D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor); + D->getElemDesc()->getAllocSize() + sizeof(InlineDescriptor); unsigned ElemOffset = 0; - auto Dtor = D->ElemDesc->DtorFn; + auto Dtor = D->getElemDesc()->DtorFn; assert(Dtor && "a composite array without an elem dtor shouldn't have a dtor itself"); for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) { auto *ElemPtr = Ptr + ElemOffset; auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr); auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1); - Dtor(B, ElemLoc, D->ElemDesc); + Dtor(B, ElemLoc, D->getElemDesc()); } } @@ -157,8 +157,8 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, const Descriptor *D, unsigned FieldOffset, bool IsVirtualBase) { assert(D); - assert(D->ElemRecord); - assert(!D->ElemRecord->isUnion()); // Unions cannot be base classes. + assert(D->getElemRecord()); + assert(!D->getElemRecord()->isUnion()); // Unions cannot be base classes. auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1; Desc->Offset = FieldOffset; @@ -172,10 +172,10 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, Desc->InUnion = InUnion; Desc->IsVolatile = false; - for (const auto &V : D->ElemRecord->bases()) + for (const auto &V : D->getElemRecord()->bases()) initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc, V.Offset, false); - for (const auto &F : D->ElemRecord->fields()) + for (const auto &F : D->getElemRecord()->fields()) initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive, InUnion, InUnion, F.Desc, F.Offset); } @@ -183,16 +183,16 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsVolatile, bool IsActive, bool InUnion, const Descriptor *D) { - for (const auto &V : D->ElemRecord->bases()) + for (const auto &V : D->getElemRecord()->bases()) initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc, V.Offset, /*IsVirtualBase=*/false); - for (const auto &F : D->ElemRecord->fields()) { + for (const auto &F : D->getElemRecord()->fields()) { bool IsUnionField = D->isUnion(); initField(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, IsUnionField, InUnion || IsUnionField, F.Desc, F.Offset); } - for (const auto &V : D->ElemRecord->virtual_bases()) + for (const auto &V : D->getElemRecord()->virtual_bases()) initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc, V.Offset, /*IsVirtualBase=*/true); @@ -207,20 +207,20 @@ static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D, static void destroyBase(Block *B, std::byte *Ptr, const Descriptor *D, unsigned FieldOffset) { assert(D); - assert(D->ElemRecord); + assert(D->getElemRecord()); - for (const auto &V : D->ElemRecord->bases()) + for (const auto &V : D->getElemRecord()->bases()) destroyBase(B, Ptr + FieldOffset, V.Desc, V.Offset); - for (const auto &F : D->ElemRecord->fields()) + for (const auto &F : D->getElemRecord()->fields()) destroyField(B, Ptr + FieldOffset, F.Desc, F.Offset); } static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) { - for (const auto &F : D->ElemRecord->bases()) + for (const auto &F : D->getElemRecord()->bases()) destroyBase(B, Ptr, F.Desc, F.Offset); - for (const auto &F : D->ElemRecord->fields()) + for (const auto &F : D->getElemRecord()->fields()) destroyField(B, Ptr, F.Desc, F.Offset); - for (const auto &F : D->ElemRecord->virtual_bases()) + for (const auto &F : D->getElemRecord()->virtual_bases()) destroyBase(B, Ptr, F.Desc, F.Offset); } @@ -282,10 +282,10 @@ static BlockDtorFn getDtorArrayPrim(PrimType Type) { Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile) - : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), Size(ElemSize), + : Source(D), SourceType(SourceTy), CtorFn(getCtorPrim(Type)), + DtorFn(getDtorPrim(Type)), ElemSize(primSize(Type)), Size(ElemSize), AllocSize(align(ElemSize)), PrimT(Type), IsConst(IsConst), - IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile), - CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)) { + IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile) { assert(Source && "Missing source"); } @@ -293,11 +293,11 @@ Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, size_t NumElems, bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile) - : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), + : Source(D), SourceType(SourceTy), CtorFn(getCtorArrayPrim(Type)), + DtorFn(getDtorArrayPrim(Type)), ElemSize(primSize(Type)), Size(ElemSize * NumElems), AllocSize(align(Size) + sizeof(InitMapPtr)), PrimT(Type), IsConst(IsConst), IsMutable(IsMutable), - IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true), - CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)) { + IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true) { assert(Source && "Missing source"); assert(NumElems <= (MaxArrayElemBytes / ElemSize)); } @@ -305,11 +305,11 @@ Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, /// Primitive unknown-size arrays. Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst, bool IsTemporary, UnknownSize) - : Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark), + : Source(D), CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)), + ElemSize(primSize(Type)), Size(UnknownSizeMark), AllocSize(sizeof(InitMapPtr) + alignof(void *)), PrimT(Type), IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary), - IsArray(true), CtorFn(getCtorArrayPrim(Type)), - DtorFn(getDtorArrayPrim(Type)) { + IsArray(true) { assert(Source && "Missing source"); } @@ -317,40 +317,41 @@ Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst, Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, const Descriptor *Elem, unsigned NumElems, bool IsConst, bool IsTemporary, bool IsMutable) - : Source(D), SourceType(SourceTy), + : Source(D), SourceType(SourceTy), ElemDescOrRecord(Elem), + CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)), Size(ElemSize * NumElems), - AllocSize(std::max<size_t>(alignof(void *), Size)), ElemDesc(Elem), - IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), - IsArray(true), CtorFn(ctorArrayDesc), - DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) { + AllocSize(std::max<size_t>(alignof(void *), Size)), IsConst(IsConst), + IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(true) { assert(Source && "Missing source"); } /// Unknown-size arrays of composite elements. Descriptor::Descriptor(DeclOrExpr D, const Descriptor *Elem, bool IsTemporary, UnknownSize) - : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)), - Size(UnknownSizeMark), AllocSize(alignof(void *)), ElemDesc(Elem), - IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true), - CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) { + : Source(D), ElemDescOrRecord(Elem), CtorFn(ctorArrayDesc), + DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr), + ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)), + Size(UnknownSizeMark), AllocSize(alignof(void *)), IsConst(true), + IsMutable(false), IsTemporary(IsTemporary), IsArray(true) { assert(Source && "Missing source"); } /// Composite records. Descriptor::Descriptor(DeclOrExpr D, const Record *R, bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile) - : Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())), - Size(ElemSize), AllocSize(Size), ElemRecord(R), IsConst(IsConst), - IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile), - CtorFn(ctorRecord), DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) { + : Source(D), ElemDescOrRecord(R), CtorFn(ctorRecord), + DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr), + ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())), + Size(ElemSize), AllocSize(Size), IsConst(IsConst), IsMutable(IsMutable), + IsTemporary(IsTemporary), IsVolatile(IsVolatile) { assert(Source && "Missing source"); } /// Dummy. Descriptor::Descriptor(DeclOrExpr D) - : Source(D), ElemSize(1), Size(1), AllocSize(0), ElemDesc(nullptr), - IsConst(true), IsMutable(false), IsTemporary(false) { + : Source(D), ElemSize(1), Size(1), AllocSize(0), IsConst(true), + IsMutable(false), IsTemporary(false) { assert(Source && "Missing source"); } @@ -364,7 +365,7 @@ QualType Descriptor::getType() const { // The Source sometimes has a different type than the once // we really save. Try to consult the Record first. if (isRecord()) { - const RecordDecl *RD = ElemRecord->getDecl(); + const RecordDecl *RD = getElemRecord()->getDecl(); QualType T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None, std::nullopt, RD, false); if (IsConst) @@ -399,7 +400,7 @@ QualType Descriptor::getElemQualType() const { } else if (const auto *TDecl = dyn_cast_if_present<TypeDecl>(asDecl())) { T = TDecl->getASTContext().getTypeDeclType(TDecl); } else if (isRecord()) { - const RecordDecl *RD = ElemRecord->getDecl(); + const RecordDecl *RD = getElemRecord()->getDecl(); T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None, std::nullopt, RD, false); if (IsConst) @@ -480,17 +481,18 @@ bool Descriptor::hasTrivialDtor() const { return true; if (isRecord()) { - assert(ElemRecord); - return ElemRecord->hasTrivialDtor(); + return getElemRecord()->hasTrivialDtor(); } - if (!ElemDesc) - return true; + if (const Descriptor *ElemDesc = getElemDescOrNull()) + return ElemDesc->hasTrivialDtor(); // Composite arrays. - return ElemDesc->hasTrivialDtor(); + return true; } -bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); } +bool Descriptor::isUnion() const { + return isRecord() && getElemRecord()->isUnion(); +} unsigned Descriptor::getElemDataSize() const { if ((isPrimitive() || isPrimitiveArray()) && diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index ee88b8bad3aee..466dddaf5b0bf 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -16,13 +16,14 @@ #include "DeclOrExpr.h" #include "InitMap.h" #include "PrimType.h" +#include "Record.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include <unistd.h> namespace clang { namespace interp { class Block; -class Record; class SourceInfo; struct Descriptor; enum PrimType : uint8_t; @@ -124,6 +125,15 @@ struct Descriptor final { /// Original declaration, used to emit the error message. const DeclOrExpr Source; const Type *SourceType = nullptr; + const llvm::PointerUnion<const Record *, const Descriptor *> + ElemDescOrRecord = nullptr; + +public: + /// Storage management methods. + const BlockCtorFn CtorFn = nullptr; + const BlockDtorFn DtorFn = nullptr; + +private: /// Size of an element, in host bytes. const unsigned ElemSize; /// Size of the storage, in host bytes. @@ -142,10 +152,6 @@ struct Descriptor final { static constexpr unsigned MaxArrayElemBytes = std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr); - /// Pointer to the record, if block contains records. - const Record *const ElemRecord = nullptr; - /// Descriptor of the array element. - const Descriptor *const ElemDesc = nullptr; /// The primitive type this descriptor was created for, /// or the primitive element type in case this is /// a primitive array. @@ -161,10 +167,6 @@ struct Descriptor final { const bool IsArray = false; bool IsConstexprUnknown = false; - /// Storage management methods. - const BlockCtorFn CtorFn = nullptr; - const BlockDtorFn DtorFn = nullptr; - /// Allocates a descriptor for a primitive. Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile); @@ -192,6 +194,19 @@ struct Descriptor final { /// Allocates a dummy descriptor. Descriptor(DeclOrExpr D); + const Descriptor *getElemDesc() const { + return cast<const Descriptor *>(ElemDescOrRecord); + } + const Descriptor *getElemDescOrNull() const { + return dyn_cast_if_present<const Descriptor *>(ElemDescOrRecord); + } + const Record *getElemRecord() const { + return cast<const Record *>(ElemDescOrRecord); + } + const Record *getElemRecordOrNull() const { + return dyn_cast_if_present<const Record *>(ElemDescOrRecord); + } + QualType getType() const; QualType getElemQualType() const; QualType getDataType(const ASTContext &Ctx) const; @@ -218,10 +233,6 @@ struct Descriptor final { return dyn_cast_if_present<RecordDecl>(asDecl()); } - template <typename T> const T *getAs() const { - return dyn_cast_if_present<T>(asDecl()); - } - /// Returns the size of the object without metadata. unsigned getSize() const { assert(!isUnknownSizeArray() && "Array of unknown size"); @@ -248,21 +259,23 @@ struct Descriptor final { } /// Checks if the descriptor is of an array of primitives. - bool isPrimitiveArray() const { return IsArray && !ElemDesc; } + bool isPrimitiveArray() const { return IsArray && !getElemDescOrNull(); } /// Checks if the descriptor is of an array of composites. - bool isCompositeArray() const { return IsArray && ElemDesc; } + bool isCompositeArray() const { return IsArray && getElemDescOrNull(); } /// Checks if the descriptor is of an array of zero size. bool isZeroSizeArray() const { return Size == 0; } /// Checks if the descriptor is of an array of unknown size. bool isUnknownSizeArray() const { return Size == UnknownSizeMark; } /// Checks if the descriptor is of a primitive. - bool isPrimitive() const { return !IsArray && !ElemRecord && PrimT; } + bool isPrimitive() const { + return !IsArray && !getElemRecordOrNull() && PrimT; + } /// Checks if the descriptor is of an array. bool isArray() const { return IsArray; } /// Checks if the descriptor is of a record. - bool isRecord() const { return !IsArray && ElemRecord; } + bool isRecord() const { return !IsArray && getElemRecordOrNull(); } /// Checks if the descriptor is of a union. bool isUnion() const; diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 9499d3a246706..f2b466171744d 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -453,9 +453,9 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { else if (isCompositeArray()) OS << " composite-array " << getNumElems(); else if (isUnion()) - OS << " union(" << ElemRecord->getName() << ")"; + OS << " union(" << getElemRecord()->getName() << ")"; else if (isRecord()) - OS << " record(" << ElemRecord->getName() << ")"; + OS << " record(" << getElemRecord()->getName() << ")"; else if (isPrimitive()) OS << " primitive " << primTypeToString(getPrimType()); @@ -484,9 +484,9 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset, for (unsigned I = 0; I != getNumElems(); ++I) { FO += sizeof(InlineDescriptor); OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n'; - ElemDesc->dumpFull(FO, Indent + 1); + getElemDesc()->dumpFull(FO, Indent + 1); - FO += ElemDesc->getAllocSize(); + FO += getElemDesc()->getAllocSize(); } } else if (isPrimitiveArray()) { OS.indent(Spaces) << "Elements: " << getNumElems() << '\n'; @@ -498,9 +498,9 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset, FO += getElemSize(); } } else if (isRecord()) { - ElemRecord->dump(OS, Indent + 1, Offset); + getElemRecord()->dump(OS, Indent + 1, Offset); unsigned I = 0; - for (const Record::Field &F : ElemRecord->fields()) { + for (const Record::Field &F : getElemRecord()->fields()) { OS.indent(Spaces) << "- Field " << I << ": "; { ColorScope SC(OS,... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/217324 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
