https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/223433
>From 0a746579cd279338e93af211cac9ae5b6bd6937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Mon, 14 Sep 2026 14:58:21 +0200 Subject: [PATCH] record alloc --- clang/lib/AST/ByteCode/Disasm.cpp | 9 +++--- clang/lib/AST/ByteCode/Program.cpp | 45 +++++++++++++++++++++++------- clang/lib/AST/ByteCode/Record.cpp | 18 +++--------- clang/lib/AST/ByteCode/Record.h | 27 +++++++----------- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 03187529541d8..9ef08855cdbb7 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -348,11 +348,10 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { Bytes += DummyVariables.getMemorySize(); // All Records. - for (const Record *R : Records.values()) { - Bytes += sizeof(Record) + R->BaseMap.getMemorySize(); - Bytes += R->Fields.capacity_in_bytes() + R->Bases.capacity_in_bytes() + - R->VirtualBases.capacity_in_bytes(); - } + // They are allocated using the program allocator, so only get the size from + // the BaseMap. + for (const Record *R : Records.values()) + Bytes += R->BaseMap.getMemorySize(); // Globals are allocated via the allocator, so already counted. diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index f7bb9540570a7..ed9f5c087c4ab 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -268,12 +268,20 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { /*IsMutable=*/false, /*IsVolatile=*/false); }; + bool HasPtrField = false; // Reserve space for base classes. - Record::BaseList Bases; - Record::VirtualBaseList VirtBases; + unsigned NumBases = 0; + Record::Base *Bases = nullptr; + unsigned NumVBases = 0; + Record::Base *VBases = nullptr; if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) { - Bases.reserve(CD->getNumBases()); + NumBases = CD->getNumBases(); + // NB: This overallocates by all explicitly specified virtual bases. + Bases = Allocate<Record::Base>(NumBases); + + unsigned I = 0; for (const CXXBaseSpecifier &Spec : CD->bases()) { + assert(I <= NumBases); if (Spec.isVirtual()) continue; @@ -288,11 +296,19 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { return nullptr; BaseSize += align(sizeof(InlineDescriptor)); - Bases.emplace_back(BD, Desc, BR, BaseSize); + new (&Bases[I]) Record::Base(BD, Desc, BR, BaseSize); BaseSize += align(BR->getSize()); + HasPtrField |= BR->hasPtrField(); + ++I; } + // Make sure we don't include the virtual base specifiers we skipped above. + NumBases = I; + I = 0; + NumVBases = CD->getNumVBases(); + VBases = Allocate<Record::Base>(NumVBases); for (const CXXBaseSpecifier &Spec : CD->vbases()) { + assert(I <= NumVBases); const auto *BD = Spec.getType()->castAsCXXRecordDecl(); const Record *BR = getOrCreateRecord(BD); @@ -301,15 +317,18 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { return nullptr; VirtSize += align(sizeof(InlineDescriptor)); - VirtBases.emplace_back(BD, Desc, BR, VirtSize); + new (&VBases[I]) Record::Base(BD, Desc, BR, VirtSize); VirtSize += align(BR->getSize()); + HasPtrField |= BR->hasPtrField(); + ++I; } + assert(I == NumVBases); } // Reserve space for fields. - Record::FieldList Fields; - Fields.reserve(RD->getNumFields()); - bool HasPtrField = false; + unsigned NumFields = RD->getNumFields(); + Record::Field *Fields = Allocate<Record::Field>(NumFields); + unsigned I = 0; for (const FieldDecl *FD : RD->fields()) { FD = FD->getFirstDecl(); // Note that we DO create fields and descriptors @@ -340,12 +359,18 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { } else { Desc = allocateDescriptor(FD); } - Fields.emplace_back(FD, Desc, BaseSize, T); + assert(Desc); + new (&Fields[I]) Record::Field(FD, Desc, BaseSize, T); BaseSize += align(Desc->getAllocSize()); + ++I; } + // Adjust virtual base offsets to account for base size. + for (unsigned I = 0; I != NumVBases; ++I) + VBases[I].Offset += BaseSize; + Record *R = new (Allocator) - Record(RD, std::move(Bases), std::move(Fields), std::move(VirtBases), + Record(RD, {Bases, NumBases}, {Fields, NumFields}, {VBases, NumVBases}, VirtSize, BaseSize, HasPtrField); Records[RD] = R; return R; diff --git a/clang/lib/AST/ByteCode/Record.cpp b/clang/lib/AST/ByteCode/Record.cpp index 7faebda880c80..4907f142ac3c0 100644 --- a/clang/lib/AST/ByteCode/Record.cpp +++ b/clang/lib/AST/ByteCode/Record.cpp @@ -12,25 +12,15 @@ using namespace clang; using namespace clang::interp; -Record::Record(const RecordDecl *Decl, BaseList &&SrcBases, - FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases, +Record::Record(const RecordDecl *Decl, ArrayRef<Base> Bases, + ArrayRef<Field> Fields, ArrayRef<Base> VirtualBases, unsigned VirtualSize, unsigned BaseSize, bool HasPtrField) - : Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)), + : Decl(Decl), Bases(Bases), Fields(Fields), VirtualBases(VirtualBases), BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()), IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()), HasPtrField(HasPtrField) { - for (Base &V : SrcVirtualBases) - VirtualBases.emplace_back(V.Decl, V.Desc, V.R, V.Offset + BaseSize); - - for (Base &B : Bases) { + for (const Base &B : this->Bases) BaseMap[B.Decl] = &B; - if (!this->HasPtrField) - this->HasPtrField |= B.R->hasPtrField(); - } - for (Base &V : VirtualBases) { - if (!this->HasPtrField) - this->HasPtrField |= V.R->hasPtrField(); - } } std::string Record::getName() const { diff --git a/clang/lib/AST/ByteCode/Record.h b/clang/lib/AST/ByteCode/Record.h index f03927bf71ffe..838643335b3b9 100644 --- a/clang/lib/AST/ByteCode/Record.h +++ b/clang/lib/AST/ByteCode/Record.h @@ -16,6 +16,7 @@ #include "PrimType.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "llvm/ADT/ArrayRef.h" namespace clang { namespace interp { @@ -61,13 +62,6 @@ class Record final { : Decl(D), Desc(Desc), R(R), Offset(Offset) {} }; - /// Mapping from identifiers to field descriptors. - using FieldList = llvm::SmallVector<Field, 8>; - /// Mapping from identifiers to base classes. - using BaseList = llvm::SmallVector<Base, 8>; - /// List of virtual base classes. - using VirtualBaseList = llvm::SmallVector<Base, 0>; - public: /// Returns the underlying declaration. const RecordDecl *getDecl() const { return Decl; } @@ -94,7 +88,7 @@ class Record final { /// with no destructor or for those with a trivial destructor. bool hasTrivialDtor() const; - using const_field_iter = FieldList::const_iterator; + using const_field_iter = ArrayRef<Field>::const_iterator; llvm::iterator_range<const_field_iter> fields() const { return llvm::make_range(Fields.begin(), Fields.end()); } @@ -109,7 +103,7 @@ class Record final { return &Fields[FD->getFieldIndex()]; } - using const_base_iter = BaseList::const_iterator; + using const_base_iter = ArrayRef<Base>::const_iterator; llvm::iterator_range<const_base_iter> bases() const { return llvm::make_range(Bases.begin(), Bases.end()); } @@ -126,8 +120,7 @@ class Record final { const Base *getBaseOrNull(const RecordDecl *RD) const; const Base *findBase(unsigned Offset) const; - using const_virtual_iter = VirtualBaseList::const_iterator; - llvm::iterator_range<const_virtual_iter> virtual_bases() const { + llvm::iterator_range<const_base_iter> virtual_bases() const { return llvm::make_range(VirtualBases.begin(), VirtualBases.end()); } @@ -142,9 +135,9 @@ class Record final { private: /// Constructor used by Program to create record descriptors. - Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields, - VirtualBaseList &&VirtualBases, unsigned VirtualSize, - unsigned BaseSize, bool HasPtrField = true); + Record(const RecordDecl *, ArrayRef<Base> Bases, ArrayRef<Field> Fields, + ArrayRef<Base> VirtualBases, unsigned VirtualSize, unsigned BaseSize, + bool HasPtrField = true); private: friend class Program; @@ -152,11 +145,11 @@ class Record final { /// Original declaration. const RecordDecl *Decl; /// List of all base classes. - BaseList Bases; + ArrayRef<Base> Bases; /// List of all the fields in the record. - FieldList Fields; + ArrayRef<Field> Fields; /// List of all virtual bases. - VirtualBaseList VirtualBases; + ArrayRef<Base> VirtualBases; /// Mapping from declarations to bases. llvm::DenseMap<const RecordDecl *, const Base *> BaseMap; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
