Skip to content

Commit

Permalink
[AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl …
Browse files Browse the repository at this point in the history
…into DeclContext

DeclContext has a little less than 8 bytes free due to the alignment
requirements on 64 bits archs. This set of patches moves the
bit-fields from classes deriving from DeclContext into DeclContext.

On 32 bits archs this increases the size of DeclContext by 4 bytes
but this is balanced by an equal or larger reduction in the size
of the classes deriving from it.

On 64 bits archs the size of DeclContext stays the same but
most of the classes deriving from it shrink by 8/16 bytes.
(-print-stats diff here https://reviews.llvm.org/D49728)
When doing an -fsyntax-only on all of Boost this result
in a 3.6% reduction in the size of all Decls and
a 1% reduction in the run time due to the lower cache
miss rate.

For now CXXRecordDecl is not touched but there is
an easy 6 (if I count correctly) bytes gain available there
by moving some bits from DefinitionData into the free
space of DeclContext. This will be the subject of another patch.

This patch sequence also enable the possibility of refactoring
FunctionDecl: To save space some bits from classes deriving from
FunctionDecl were moved to FunctionDecl. This resulted in a
lot of stuff in FunctionDecl which do not belong logically to it.
After this set of patches however it is just a simple matter of
adding a SomethingDeclBitfields in DeclContext and moving the
bits to it from FunctionDecl.

This first patch introduces the anonymous union in DeclContext
and all the *DeclBitfields classes holding the bit-fields, and moves
the bits from TagDecl, EnumDecl and RecordDecl into DeclContext.

This patch is followed by https://reviews.llvm.org/D49732,
https://reviews.llvm.org/D49733 and https://reviews.llvm.org/D49734.

Differential Revision: https://reviews.llvm.org/D49729

Patch By: bricci

llvm-svn: 338630
  • Loading branch information
Erich Keane committed Aug 1, 2018
1 parent 7f33094 commit f92f31c
Show file tree
Hide file tree
Showing 9 changed files with 775 additions and 312 deletions.
304 changes: 129 additions & 175 deletions clang/include/clang/AST/Decl.h

Large diffs are not rendered by default.

584 changes: 519 additions & 65 deletions clang/include/clang/AST/DeclBase.h

Large diffs are not rendered by default.

75 changes: 55 additions & 20 deletions clang/lib/AST/Decl.cpp
Expand Up @@ -3767,6 +3767,22 @@ void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) {
// TagDecl Implementation
//===----------------------------------------------------------------------===//

TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
SourceLocation StartL)
: TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
setPreviousDecl(PrevDecl);
setTagKind(TK);
setCompleteDefinition(false);
setBeingDefined(false);
setEmbeddedInDeclarator(false);
setFreeStanding(false);
setCompleteDefinitionRequired(false);
}

SourceLocation TagDecl::getOuterLocStart() const {
return getTemplateOrInnerLocStart(this);
}
Expand All @@ -3789,7 +3805,7 @@ void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
}

void TagDecl::startDefinition() {
IsBeingDefined = true;
setBeingDefined(true);

if (auto *D = dyn_cast<CXXRecordDecl>(this)) {
struct CXXRecordDecl::DefinitionData *Data =
Expand All @@ -3804,8 +3820,8 @@ void TagDecl::completeDefinition() {
cast<CXXRecordDecl>(this)->hasDefinition()) &&
"definition completed but not started");

IsCompleteDefinition = true;
IsBeingDefined = false;
setCompleteDefinition(true);
setBeingDefined(false);

if (ASTMutationListener *L = getASTMutationListener())
L->CompletedTagDefinition(this);
Expand All @@ -3816,7 +3832,7 @@ TagDecl *TagDecl::getDefinition() const {
return const_cast<TagDecl *>(this);

// If it's possible for us to have an out-of-date definition, check now.
if (MayHaveOutOfDateDef) {
if (mayHaveOutOfDateDef()) {
if (IdentifierInfo *II = getIdentifier()) {
if (II->isOutOfDate()) {
updateOutOfDate(*II);
Expand Down Expand Up @@ -3869,6 +3885,21 @@ void TagDecl::setTemplateParameterListsInfo(
// EnumDecl Implementation
//===----------------------------------------------------------------------===//

EnumDecl::EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
: TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = nullptr;
setNumPositiveBits(0);
setNumNegativeBits(0);
setScoped(Scoped);
setScopedUsingClassTag(ScopedUsingClassTag);
setFixed(Fixed);
setHasODRHash(false);
ODRHash = 0;
}

void EnumDecl::anchor() {}

EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
Expand All @@ -3878,7 +3909,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
bool IsScopedUsingClassTag, bool IsFixed) {
auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
IsScoped, IsScopedUsingClassTag, IsFixed);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
C.getTypeDeclType(Enum, PrevDecl);
return Enum;
}
Expand All @@ -3887,7 +3918,7 @@ EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
EnumDecl *Enum =
new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
nullptr, nullptr, false, false, false);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
return Enum;
}

Expand Down Expand Up @@ -3971,12 +4002,12 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
}

unsigned EnumDecl::getODRHash() {
if (HasODRHash)
if (hasODRHash())
return ODRHash;

class ODRHash Hash;
Hash.AddEnumDecl(this);
HasODRHash = true;
setHasODRHash(true);
ODRHash = Hash.CalculateHash();
return ODRHash;
}
Expand All @@ -3989,22 +4020,26 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
RecordDecl *PrevDecl)
: TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc),
HasFlexibleArrayMember(false), AnonymousStructOrUnion(false),
HasObjectMember(false), HasVolatileMember(false),
LoadedFieldsFromExternalStorage(false),
NonTrivialToPrimitiveDefaultInitialize(false),
NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false),
ParamDestroyedInCallee(false), ArgPassingRestrictions(APK_CanPassInRegs) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
: TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
assert(classof(static_cast<Decl *>(this)) && "Invalid Kind!");
setHasFlexibleArrayMember(false);
setAnonymousStructOrUnion(false);
setHasObjectMember(false);
setHasVolatileMember(false);
setHasLoadedFieldsFromExternalStorage(false);
setNonTrivialToPrimitiveDefaultInitialize(false);
setNonTrivialToPrimitiveCopy(false);
setNonTrivialToPrimitiveDestroy(false);
setParamDestroyedInCallee(false);
setArgPassingRestrictions(APK_CanPassInRegs);
}

RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl) {
RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
StartLoc, IdLoc, Id, PrevDecl);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);

C.getTypeDeclType(R, PrevDecl);
return R;
Expand All @@ -4014,7 +4049,7 @@ RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
RecordDecl *R =
new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
SourceLocation(), nullptr, nullptr);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
return R;
}

Expand All @@ -4038,7 +4073,7 @@ void RecordDecl::setCapturedRecord() {
}

RecordDecl::field_iterator RecordDecl::field_begin() const {
if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage)
if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
LoadFieldsFromExternalStorage();

return field_iterator(decl_iterator(FirstDecl));
Expand Down Expand Up @@ -4066,7 +4101,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
ExternalASTSource::Deserializing TheFields(Source);

SmallVector<Decl*, 64> Decls;
LoadedFieldsFromExternalStorage = true;
setHasLoadedFieldsFromExternalStorage(true);
Source->FindExternalLexicalDecls(this, [](Decl::Kind K) {
return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
}, Decls);
Expand Down

0 comments on commit f92f31c

Please sign in to comment.