llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nikolas Klauser (philnik777) <details> <summary>Changes</summary> Class | Old size (in bytes) | New size (in bytes) ----------------------------------|---------------------|-------------------- Decl | 40 | 32 AccessSpecDecl | 40 | 40 BlockDecl | 128 | 120 CapturedDecl | 88 | 80 EmptyDecl | 40 | 32 ExportDecl | 80 | 72 ExternCContextDecl | 72 | 64 FileScopeAsmDecl | 56 | 48 FriendDecl | 64 | 56 FriendTemplateDecl | 64 | 64 ImplicitConceptSpecializationDecl | 40 | 40 ImportDecl | 56 | 48 LifetimeExtendedTemporaryDecl | 72 | 64 LinkageSpecDecl | 80 | 72 NamedDecl | 48 | 40 ObjCPropertyImplDecl | 96 | 88 PragmaCommentDecl | 40 | 40 PragmaDetectMismatchDecl | 48 | 40 RequiresExprBodyDecl | 72 | 64 StaticAssertDecl | 64 | 56 TopLevelStmtDecl | 88 | 80 TranslationUnitDecl | 104 | 96 BaseUsingDecl | 56 | 48 UsingDecl | 88 | 80 UsingEnumDecl | 72 | 64 HLSLBufferDecl | 96 | 88 LabelDecl | 80 | 72 NamespaceAliasDecl | 96 | 88 NamespaceDecl | 112 | 104 ObjCCompatibleAliasDecl | 56 | 48 ObjCContainerDecl | 88 | 80 ObjCMethodDecl | 136 | 128 ObjCPropertyDecl | 128 | 120 TemplateDecl | 64 | 56 BuiltinTemplateDecl | 72 | 64 TypeDecl | 64 | 56 UnresolvedUsingIfExistsDecl | 48 | 40 UsingDirectiveDecl | 88 | 80 UsingPackDecl | 64 | 56 UsingShadowDecl | 80 | 72 ValueDecl | 56 | 48 When parsing libc++'s `<string>` header the used memory is reduced from 42.8MB to 42.5MB. --- Full diff: https://github.com/llvm/llvm-project/pull/87361.diff 3 Files Affected: - (modified) clang/include/clang/AST/DeclBase.h (+44-25) - (modified) clang/lib/AST/DeclBase.cpp (+22-9) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+1-1) ``````````diff diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 47ed6d0d1db0df..9a3f8c41de387e 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -268,17 +268,37 @@ class alignas(8) Decl { /// } /// void A::f(); // SemanticDC == namespace 'A' /// // LexicalDC == global namespace - llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; - bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } - bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } + // Compress the InvalidDecl and HasAttrs bits into DeclCtx to keep Decl below + // 32 bytes in size + llvm::PointerIntPair< + llvm::PointerIntPair<llvm::PointerUnion<DeclContext *, MultipleDC *>, 1, + bool>, + 1, bool> + DeclCtxWithInvalidDeclAndHasAttrs; + + bool isInSemaDC() const { + return DeclCtxWithInvalidDeclAndHasAttrs.getPointer() + .getPointer() + .is<DeclContext *>(); + } + + bool isOutOfSemaDC() const { + return DeclCtxWithInvalidDeclAndHasAttrs.getPointer() + .getPointer() + .is<MultipleDC *>(); + } MultipleDC *getMultipleDC() const { - return DeclCtx.get<MultipleDC*>(); + return DeclCtxWithInvalidDeclAndHasAttrs.getPointer() + .getPointer() + .get<MultipleDC *>(); } DeclContext *getSemanticDC() const { - return DeclCtx.get<DeclContext*>(); + return DeclCtxWithInvalidDeclAndHasAttrs.getPointer() + .getPointer() + .get<DeclContext *>(); } /// Loc - The location of this decl. @@ -288,14 +308,6 @@ class alignas(8) Decl { LLVM_PREFERRED_TYPE(Kind) unsigned DeclKind : 7; - /// InvalidDecl - This indicates a semantic error occurred. - LLVM_PREFERRED_TYPE(bool) - unsigned InvalidDecl : 1; - - /// HasAttrs - This indicates whether the decl has attributes or not. - LLVM_PREFERRED_TYPE(bool) - unsigned HasAttrs : 1; - /// Implicit - Whether this declaration was implicitly generated by /// the implementation rather than explicitly written by the user. LLVM_PREFERRED_TYPE(bool) @@ -393,21 +405,22 @@ class alignas(8) Decl { protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), - DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), - Implicit(false), Used(false), Referenced(false), + DeclCtxWithInvalidDeclAndHasAttrs({DC, false}, false), Loc(L), + DeclKind(DK), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) { - if (StatisticsEnabled) add(DK); + if (StatisticsEnabled) + add(DK); } Decl(Kind DK, EmptyShell Empty) - : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), - Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), - Access(AS_none), FromASTFile(0), + : DeclKind(DK), Implicit(false), Used(false), Referenced(false), + TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) { - if (StatisticsEnabled) add(DK); + if (StatisticsEnabled) + add(DK); } virtual ~Decl(); @@ -520,7 +533,7 @@ class alignas(8) Decl { return AccessSpecifier(Access); } - bool hasAttrs() const { return HasAttrs; } + bool hasAttrs() const { return DeclCtxWithInvalidDeclAndHasAttrs.getPointer().getInt(); } void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); @@ -549,13 +562,16 @@ class alignas(8) Decl { } template <typename... Ts> void dropAttrs() { - if (!HasAttrs) return; + if (!hasAttrs()) return; AttrVec &Vec = getAttrs(); llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); }); - if (Vec.empty()) - HasAttrs = false; + if (Vec.empty()) { + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setInt(false); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); + } } template <typename T> void dropAttr() { dropAttrs<T>(); } @@ -590,7 +606,10 @@ class alignas(8) Decl { /// setInvalidDecl - Indicates the Decl had a semantic error. This /// allows for graceful error recovery. void setInvalidDecl(bool Invalid = true); - bool isInvalidDecl() const { return (bool) InvalidDecl; } + + bool isInvalidDecl() const { + return DeclCtxWithInvalidDeclAndHasAttrs.getInt(); + } /// isImplicit - Indicates whether the declaration was implicitly /// generated by the implementation. If false, this declaration diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 04bbc49ab2f319..c06b41d6b29f89 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -52,6 +52,8 @@ using namespace clang; +static_assert(sizeof(Decl) <= 32, "Decl grew beyond 32 bytes!"); + //===----------------------------------------------------------------------===// // Statistics //===----------------------------------------------------------------------===// @@ -130,7 +132,7 @@ const char *Decl::getDeclKindName() const { } void Decl::setInvalidDecl(bool Invalid) { - InvalidDecl = Invalid; + DeclCtxWithInvalidDeclAndHasAttrs.setInt(Invalid); assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition()); if (!Invalid) { return; @@ -334,7 +336,9 @@ void PrettyStackTraceDecl::print(raw_ostream &OS) const { Decl::~Decl() = default; void Decl::setDeclContext(DeclContext *DC) { - DeclCtx = DC; + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setPointer(DC); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); } void Decl::setLexicalDeclContext(DeclContext *DC) { @@ -364,12 +368,16 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, ASTContext &Ctx) { if (SemaDC == LexicalDC) { - DeclCtx = SemaDC; + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setPointer(SemaDC); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); } else { auto *MDC = new (Ctx) Decl::MultipleDC(); MDC->SemanticDC = SemaDC; MDC->LexicalDC = LexicalDC; - DeclCtx = MDC; + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setPointer(MDC); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); } } @@ -956,19 +964,24 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { } void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) { - assert(!HasAttrs && "Decl already contains attrs."); + assert(!hasAttrs() && "Decl already contains attrs."); AttrVec &AttrBlank = Ctx.getDeclAttrs(this); assert(AttrBlank.empty() && "HasAttrs was wrong?"); AttrBlank = attrs; - HasAttrs = true; + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setInt(true); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); } void Decl::dropAttrs() { - if (!HasAttrs) return; + if (!hasAttrs()) + return; - HasAttrs = false; + auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer(); + InnerPtr.setInt(false); + DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr); getASTContext().eraseDeclAttrs(this); } @@ -996,7 +1009,7 @@ void Decl::addAttr(Attr *A) { } const AttrVec &Decl::getAttrs() const { - assert(HasAttrs && "No attrs to get!"); + assert(hasAttrs() && "No attrs to get!"); return getASTContext().getDeclAttrs(this); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a22f760408c634..2e186109327fb2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -594,7 +594,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { bool HasStandaloneLexicalDC = DeclBits.getNextBit(); bool HasAttrs = DeclBits.getNextBit(); D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit()); - D->InvalidDecl = DeclBits.getNextBit(); + D->DeclCtxWithInvalidDeclAndHasAttrs.setInt(DeclBits.getNextBit()); D->FromASTFile = true; if (D->isTemplateParameter() || D->isTemplateParameterPack() || `````````` </details> https://github.com/llvm/llvm-project/pull/87361 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits