[clang] bfa3da8 - [clang][bytecode] Optimize `interp::Record` a bit (#183494)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 26 04:34:37 PST 2026
Author: Timm Baeder
Date: 2026-02-26T13:34:31+01:00
New Revision: bfa3da861342372bbfd7ee8e2d80bc52feb8d57e
URL: https://github.com/llvm/llvm-project/commit/bfa3da861342372bbfd7ee8e2d80bc52feb8d57e
DIFF: https://github.com/llvm/llvm-project/commit/bfa3da861342372bbfd7ee8e2d80bc52feb8d57e.diff
LOG: [clang][bytecode] Optimize `interp::Record` a bit (#183494)
And things around it.
Remove the `FieldMap`, since we can use the field's index instead and
only keep an array around. `reserve()` the sizes and use
`emplace_back()`.
Added:
Modified:
clang/lib/AST/ByteCode/Program.cpp
clang/lib/AST/ByteCode/Record.cpp
clang/lib/AST/ByteCode/Record.h
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 76fec63a8920d..9a7b38d4d828e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -319,6 +319,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
Record::BaseList Bases;
Record::VirtualBaseList VirtBases;
if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
+ Bases.reserve(CD->getNumBases());
for (const CXXBaseSpecifier &Spec : CD->bases()) {
if (Spec.isVirtual())
continue;
@@ -334,7 +335,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
return nullptr;
BaseSize += align(sizeof(InlineDescriptor));
- Bases.push_back({BD, BaseSize, Desc, BR});
+ Bases.emplace_back(BD, Desc, BR, BaseSize);
BaseSize += align(BR->getSize());
}
@@ -347,13 +348,14 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
return nullptr;
VirtSize += align(sizeof(InlineDescriptor));
- VirtBases.push_back({BD, VirtSize, Desc, BR});
+ VirtBases.emplace_back(BD, Desc, BR, VirtSize);
VirtSize += align(BR->getSize());
}
}
// Reserve space for fields.
Record::FieldList Fields;
+ Fields.reserve(RD->getNumFields());
for (const FieldDecl *FD : RD->fields()) {
FD = FD->getFirstDecl();
// Note that we DO create fields and descriptors
@@ -378,7 +380,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
}
if (!Desc)
return nullptr;
- Fields.push_back({FD, BaseSize, Desc});
+ Fields.emplace_back(FD, Desc, BaseSize);
BaseSize += align(Desc->getAllocSize());
}
diff --git a/clang/lib/AST/ByteCode/Record.cpp b/clang/lib/AST/ByteCode/Record.cpp
index ff5c82d244574..17cf629a91b60 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -19,12 +19,10 @@ Record::Record(const RecordDecl *Decl, BaseList &&SrcBases,
BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()),
IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()) {
for (Base &V : SrcVirtualBases)
- VirtualBases.push_back({V.Decl, V.Offset + BaseSize, V.Desc, V.R});
+ VirtualBases.emplace_back(V.Decl, V.Desc, V.R, V.Offset + BaseSize);
for (Base &B : Bases)
BaseMap[B.Decl] = &B;
- for (Field &F : Fields)
- FieldMap[F.Decl] = &F;
for (Base &V : VirtualBases)
VirtualBaseMap[V.Decl] = &V;
}
@@ -44,12 +42,6 @@ bool Record::hasTrivialDtor() const {
return !Dtor || Dtor->isTrivial();
}
-const Record::Field *Record::getField(const FieldDecl *FD) const {
- auto It = FieldMap.find(FD->getFirstDecl());
- assert(It != FieldMap.end() && "Missing field");
- return It->second;
-}
-
const Record::Base *Record::getBase(const RecordDecl *FD) const {
auto It = BaseMap.find(FD);
assert(It != BaseMap.end() && "Missing base");
diff --git a/clang/lib/AST/ByteCode/Record.h b/clang/lib/AST/ByteCode/Record.h
index 7b66c3b263e38..29c500b9c29d5 100644
--- a/clang/lib/AST/ByteCode/Record.h
+++ b/clang/lib/AST/ByteCode/Record.h
@@ -13,13 +13,13 @@
#ifndef LLVM_CLANG_AST_INTERP_RECORD_H
#define LLVM_CLANG_AST_INTERP_RECORD_H
-#include "Descriptor.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
namespace clang {
namespace interp {
class Program;
+struct Descriptor;
/// Structure/Class descriptor.
class Record final {
@@ -27,18 +27,26 @@ class Record final {
/// Describes a record field.
struct Field {
const FieldDecl *Decl;
- unsigned Offset;
const Descriptor *Desc;
+ unsigned Offset;
+
bool isBitField() const { return Decl->isBitField(); }
bool isUnnamedBitField() const { return Decl->isUnnamedBitField(); }
+
+ Field(const FieldDecl *D, const Descriptor *Desc, unsigned Offset)
+ : Decl(D), Desc(Desc), Offset(Offset) {}
};
/// Describes a base class.
struct Base {
const RecordDecl *Decl;
- unsigned Offset;
const Descriptor *Desc;
const Record *R;
+ unsigned Offset;
+
+ Base(const RecordDecl *D, const Descriptor *Desc, const Record *R,
+ unsigned Offset)
+ : Decl(D), Desc(Desc), R(R), Offset(Offset) {}
};
/// Mapping from identifiers to field descriptors.
@@ -46,7 +54,7 @@ class Record final {
/// Mapping from identifiers to base classes.
using BaseList = llvm::SmallVector<Base, 8>;
/// List of virtual base classes.
- using VirtualBaseList = llvm::SmallVector<Base, 2>;
+ using VirtualBaseList = llvm::SmallVector<Base, 0>;
public:
/// Returns the underlying declaration.
@@ -80,7 +88,9 @@ class Record final {
unsigned getNumFields() const { return Fields.size(); }
const Field *getField(unsigned I) const { return &Fields[I]; }
/// Returns a field.
- const Field *getField(const FieldDecl *FD) const;
+ const Field *getField(const FieldDecl *FD) const {
+ return &Fields[FD->getFieldIndex()];
+ }
using const_base_iter = BaseList::const_iterator;
llvm::iterator_range<const_base_iter> bases() const {
@@ -131,8 +141,6 @@ class Record final {
/// Mapping from declarations to bases.
llvm::DenseMap<const RecordDecl *, const Base *> BaseMap;
- /// Mapping from field identifiers to descriptors.
- llvm::DenseMap<const FieldDecl *, const Field *> FieldMap;
/// Mapping from declarations to virtual bases.
llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap;
/// Size of the structure.
More information about the cfe-commits
mailing list