[clang] [NFC] [Serializer] Pack information in serializer (PR #69287)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 16 22:22:32 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-modules

Author: Chuanqi Xu (ChuanqiXu9)

<details>
<summary>Changes</summary>

Previously, the boolean values will occupy spaces that can contain integers. It wastes the spaces especially if the boolean values are serialized consecutively. The patch tries to pack such consecutive boolean values (and enum values) so that we can save more spaces and so the times.

Before the patch, we need 4.478s (in my machine) to build the std module (https://libcxx.llvm.org/Modules.html) with 28712 bytes. After the patch, the time becomes to 4.374s and the size becomes to 27568 bytes.

This is intended to be a NFC patch.

This patch doesn't optimize all such cases. We can do it later after we have consensus on this.

---

Patch is 45.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/69287.diff


5 Files Affected:

- (modified) clang/include/clang/AST/Decl.h (+1-1) 
- (modified) clang/include/clang/AST/DeclBase.h (+1-1) 
- (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+103-88) 
- (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+155-240) 
- (modified) clang/test/Modules/decl-params-determinisim.m (+8-8) 


``````````diff
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7f076cc77ea82cb..cd9a830dbaaf426 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4073,7 +4073,7 @@ class RecordDecl : public TagDecl {
   /// returned from function calls. This takes into account the target-specific
   /// and version-specific rules along with the rules determined by the
   /// language.
-  enum ArgPassingKind : unsigned {
+  enum ArgPassingKind : unsigned char {
     /// The argument of this type can be passed directly in registers.
     APK_CanPassInRegs,
 
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index d383e46e22e16f4..7a30529f1f73d74 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -211,7 +211,7 @@ class alignas(8) Decl {
   /// The kind of ownership a declaration has, for visibility purposes.
   /// This enumeration is designed such that higher values represent higher
   /// levels of name hiding.
-  enum class ModuleOwnershipKind : unsigned {
+  enum class ModuleOwnershipKind : unsigned char {
     /// This declaration is not owned by a module.
     Unowned,
 
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 3a3477c39efae25..62b2665c2211029 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -617,24 +617,27 @@ void ASTDeclReader::VisitDecl(Decl *D) {
                            Reader.getContext());
   }
   D->setLocation(ThisDeclLoc);
-  D->InvalidDecl = Record.readInt();
-  if (Record.readInt()) { // hasAttrs
+
+  uint64_t DeclBits = Record.readInt();
+  D->InvalidDecl = DeclBits & 0x1;
+  D->setImplicit(DeclBits & (1 << 2));
+  D->Used = (DeclBits >> 3) & 0x1;
+  IsDeclMarkedUsed |= D->Used;
+  D->setReferenced(DeclBits & (1 << 4));
+  D->setTopLevelDeclInObjCContainer(DeclBits & (1 << 5));
+  D->setAccess((AccessSpecifier)((DeclBits >> 6) & 0x3));
+  D->FromASTFile = true;
+  auto ModuleOwnership = (Decl::ModuleOwnershipKind)((DeclBits >> 8) & 0x7);
+  bool ModulePrivate =
+      (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
+
+  if (DeclBits & (0x1 << 1)) { // hasAttrs
     AttrVec Attrs;
     Record.readAttributes(Attrs);
     // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
     // internally which is unsafe during derialization.
     D->setAttrsImpl(Attrs, Reader.getContext());
   }
-  D->setImplicit(Record.readInt());
-  D->Used = Record.readInt();
-  IsDeclMarkedUsed |= D->Used;
-  D->setReferenced(Record.readInt());
-  D->setTopLevelDeclInObjCContainer(Record.readInt());
-  D->setAccess((AccessSpecifier)Record.readInt());
-  D->FromASTFile = true;
-  auto ModuleOwnership = (Decl::ModuleOwnershipKind)Record.readInt();
-  bool ModulePrivate =
-      (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
 
   // Determine whether this declaration is part of a (sub)module. If so, it
   // may not yet be visible.
@@ -750,12 +753,14 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
   VisitTypeDecl(TD);
 
   TD->IdentifierNamespace = Record.readInt();
-  TD->setTagKind((TagDecl::TagKind)Record.readInt());
+
+  uint32_t TagDeclBits = Record.readInt();
+  TD->setTagKind((TagDecl::TagKind)(TagDeclBits & 0x7));
   if (!isa<CXXRecordDecl>(TD))
-    TD->setCompleteDefinition(Record.readInt());
-  TD->setEmbeddedInDeclarator(Record.readInt());
-  TD->setFreeStanding(Record.readInt());
-  TD->setCompleteDefinitionRequired(Record.readInt());
+    TD->setCompleteDefinition(TagDeclBits & (0x1 << 3));
+  TD->setEmbeddedInDeclarator(TagDeclBits & (0x1 << 4));
+  TD->setFreeStanding(TagDeclBits & (0x1 << 5));
+  TD->setCompleteDefinitionRequired(TagDeclBits & (0x1 << 6));
   TD->setBraceRange(readSourceRange());
 
   switch (Record.readInt()) {
@@ -787,11 +792,13 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
   else
     ED->setIntegerType(Record.readType());
   ED->setPromotionType(Record.readType());
-  ED->setNumPositiveBits(Record.readInt());
-  ED->setNumNegativeBits(Record.readInt());
-  ED->setScoped(Record.readInt());
-  ED->setScopedUsingClassTag(Record.readInt());
-  ED->setFixed(Record.readInt());
+
+  uint32_t EnumDeclBits = Record.readInt();
+  ED->setNumPositiveBits(EnumDeclBits & 0xff);
+  ED->setNumNegativeBits((EnumDeclBits >> 8) & 0xff);
+  ED->setScoped(EnumDeclBits & (1 << 16));
+  ED->setScopedUsingClassTag(EnumDeclBits & (1 << 17));
+  ED->setFixed(EnumDeclBits & (1 << 18));
 
   ED->setHasODRHash(true);
   ED->ODRHash = Record.readInt();
@@ -834,18 +841,20 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
   RedeclarableResult Redecl = VisitTagDecl(RD);
-  RD->setHasFlexibleArrayMember(Record.readInt());
-  RD->setAnonymousStructOrUnion(Record.readInt());
-  RD->setHasObjectMember(Record.readInt());
-  RD->setHasVolatileMember(Record.readInt());
-  RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt());
-  RD->setNonTrivialToPrimitiveCopy(Record.readInt());
-  RD->setNonTrivialToPrimitiveDestroy(Record.readInt());
-  RD->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(Record.readInt());
-  RD->setHasNonTrivialToPrimitiveDestructCUnion(Record.readInt());
-  RD->setHasNonTrivialToPrimitiveCopyCUnion(Record.readInt());
-  RD->setParamDestroyedInCallee(Record.readInt());
-  RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt());
+
+  uint32_t RecordDeclBits = Record.readInt();
+  RD->setHasFlexibleArrayMember(RecordDeclBits & 0x1);
+  RD->setAnonymousStructOrUnion(RecordDeclBits & (1 << 1));
+  RD->setHasObjectMember(RecordDeclBits & (1 << 2));
+  RD->setHasVolatileMember(RecordDeclBits & (1 << 3));
+  RD->setNonTrivialToPrimitiveDefaultInitialize(RecordDeclBits & (1 << 4));
+  RD->setNonTrivialToPrimitiveCopy(RecordDeclBits & (1 << 5));
+  RD->setNonTrivialToPrimitiveDestroy(RecordDeclBits & (1 << 6));
+  RD->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(RecordDeclBits & (1 << 7));
+  RD->setHasNonTrivialToPrimitiveDestructCUnion(RecordDeclBits & (1 << 8));
+  RD->setHasNonTrivialToPrimitiveCopyCUnion(RecordDeclBits & (1 << 9));
+  RD->setParamDestroyedInCallee(RecordDeclBits & (1 << 10));
+  RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)((RecordDeclBits >> 11) & 0x3));
   return Redecl;
 }
 
@@ -1046,32 +1055,33 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
 
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
+  uint64_t FunctionDeclBits = Record.readInt();
 
-  FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
-  FD->setInlineSpecified(Record.readInt());
-  FD->setImplicitlyInline(Record.readInt());
-  FD->setVirtualAsWritten(Record.readInt());
+  FD->setStorageClass(static_cast<StorageClass>(FunctionDeclBits & 0x7));
+  FD->setInlineSpecified(FunctionDeclBits & (1 << 3));
+  FD->setImplicitlyInline(FunctionDeclBits & (1 << 4));
+  FD->setVirtualAsWritten(FunctionDeclBits & (1 << 5));
   // We defer calling `FunctionDecl::setPure()` here as for methods of
   // `CXXTemplateSpecializationDecl`s, we may not have connected up the
   // definition (which is required for `setPure`).
-  const bool Pure = Record.readInt();
-  FD->setHasInheritedPrototype(Record.readInt());
-  FD->setHasWrittenPrototype(Record.readInt());
-  FD->setDeletedAsWritten(Record.readInt());
-  FD->setTrivial(Record.readInt());
-  FD->setTrivialForCall(Record.readInt());
-  FD->setDefaulted(Record.readInt());
-  FD->setExplicitlyDefaulted(Record.readInt());
-  FD->setIneligibleOrNotSelected(Record.readInt());
-  FD->setHasImplicitReturnZero(Record.readInt());
-  FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt()));
-  FD->setUsesSEHTry(Record.readInt());
-  FD->setHasSkippedBody(Record.readInt());
-  FD->setIsMultiVersion(Record.readInt());
-  FD->setLateTemplateParsed(Record.readInt());
-  FD->setFriendConstraintRefersToEnclosingTemplate(Record.readInt());
-
-  FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
+  const bool Pure = FunctionDeclBits & (1 << 6);
+  FD->setHasInheritedPrototype(FunctionDeclBits & (1 << 7));
+  FD->setHasWrittenPrototype(FunctionDeclBits & (1 << 8));
+  FD->setDeletedAsWritten(FunctionDeclBits & (1 << 9));
+  FD->setTrivial(FunctionDeclBits & (1 << 10));
+  FD->setTrivialForCall(FunctionDeclBits & (1 << 11));
+  FD->setDefaulted(FunctionDeclBits & (1 << 12));
+  FD->setExplicitlyDefaulted(FunctionDeclBits & (1 << 13));
+  FD->setIneligibleOrNotSelected(FunctionDeclBits & (1 << 14));
+  FD->setHasImplicitReturnZero(FunctionDeclBits & (1 << 15));
+  FD->setConstexprKind(static_cast<ConstexprSpecKind>((FunctionDeclBits >> 16) & 0x3));
+  FD->setUsesSEHTry(FunctionDeclBits & (1 << 18));
+  FD->setHasSkippedBody(FunctionDeclBits & (1 << 19));
+  FD->setIsMultiVersion(FunctionDeclBits & (1 << 20));
+  FD->setLateTemplateParsed(FunctionDeclBits & (1 << 21));
+  FD->setFriendConstraintRefersToEnclosingTemplate(FunctionDeclBits & (1 << 22));
+  FD->setCachedLinkage(static_cast<Linkage>((FunctionDeclBits >> 23) & 0x7));
+
   FD->EndRangeLoc = readSourceLocation();
   FD->setDefaultLoc(readSourceLocation());
 
@@ -1574,26 +1584,27 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
   RedeclarableResult Redecl = VisitRedeclarable(VD);
   VisitDeclaratorDecl(VD);
 
-  VD->VarDeclBits.SClass = (StorageClass)Record.readInt();
-  VD->VarDeclBits.TSCSpec = Record.readInt();
-  VD->VarDeclBits.InitStyle = Record.readInt();
-  VD->VarDeclBits.ARCPseudoStrong = Record.readInt();
+  uint32_t RecordDeclBits = Record.readInt();
+  VD->VarDeclBits.SClass = (StorageClass)(RecordDeclBits & 0x7);
+  VD->VarDeclBits.TSCSpec = (RecordDeclBits >> 3) & 0x3;
+  VD->VarDeclBits.InitStyle = (RecordDeclBits >> 5) & 0x3;
+  VD->VarDeclBits.ARCPseudoStrong = (bool)(RecordDeclBits & (1 << 7));
   bool HasDeducedType = false;
   if (!isa<ParmVarDecl>(VD)) {
     VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition =
-        Record.readInt();
-    VD->NonParmVarDeclBits.ExceptionVar = Record.readInt();
-    VD->NonParmVarDeclBits.NRVOVariable = Record.readInt();
-    VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt();
-    VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt();
-    VD->NonParmVarDeclBits.IsInline = Record.readInt();
-    VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
-    VD->NonParmVarDeclBits.IsConstexpr = Record.readInt();
-    VD->NonParmVarDeclBits.IsInitCapture = Record.readInt();
-    VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt();
-    VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt();
-    VD->NonParmVarDeclBits.EscapingByref = Record.readInt();
-    HasDeducedType = Record.readInt();
+         (bool)(RecordDeclBits & (1 << 8));
+    VD->NonParmVarDeclBits.ExceptionVar = (bool)(RecordDeclBits & (1 << 9));
+    VD->NonParmVarDeclBits.NRVOVariable = (bool)(RecordDeclBits & (1 << 10));
+    VD->NonParmVarDeclBits.CXXForRangeDecl = (bool)(RecordDeclBits & (1 << 11));
+    VD->NonParmVarDeclBits.ObjCForDecl = (bool)(RecordDeclBits & (1 << 12));
+    VD->NonParmVarDeclBits.IsInline = (bool)(RecordDeclBits & (1 << 13));
+    VD->NonParmVarDeclBits.IsInlineSpecified = (bool)(RecordDeclBits & (1 << 14));
+    VD->NonParmVarDeclBits.IsConstexpr = (bool)(RecordDeclBits & (1 << 15));
+    VD->NonParmVarDeclBits.IsInitCapture = (bool)(RecordDeclBits & (1 << 16));
+    VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = (bool)(RecordDeclBits & (1 << 17));
+    VD->NonParmVarDeclBits.ImplicitParamKind = (RecordDeclBits >> 18) & 0x7;
+    VD->NonParmVarDeclBits.EscapingByref = (bool)(RecordDeclBits & (1 << 21));
+    HasDeducedType = (bool)(RecordDeclBits & (1 << 22));
   }
 
   // If this variable has a deduced type, defer reading that type until we are
@@ -1605,7 +1616,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
     VD->setType(Reader.GetType(DeferredTypeID));
   DeferredTypeID = 0;
 
-  auto VarLinkage = Linkage(Record.readInt());
+  auto VarLinkage = Linkage((RecordDeclBits >> 23) & 0x7);
   VD->setCachedLinkage(VarLinkage);
 
   // Reconstruct the one piece of the IdentifierNamespace that we need.
@@ -1613,18 +1624,18 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
       VD->getLexicalDeclContext()->isFunctionOrMethod())
     VD->setLocalExternDecl();
 
+  if (RecordDeclBits & (1 << 26)) {
+    Reader.DefinitionSource[VD] =
+        Loc.F->Kind == ModuleKind::MK_MainFile ||
+        Reader.getContext().getLangOpts().BuildingPCHWithObjectFile;
+  }
+
   if (VD->hasAttr<BlocksAttr>()) {
     Expr *CopyExpr = Record.readExpr();
     if (CopyExpr)
       Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt());
   }
 
-  if (Record.readInt()) {
-    Reader.DefinitionSource[VD] =
-        Loc.F->Kind == ModuleKind::MK_MainFile ||
-        Reader.getContext().getLangOpts().BuildingPCHWithObjectFile;
-  }
-
   enum VarKind {
     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
   };
@@ -1678,9 +1689,11 @@ void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
 
 void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
   VisitVarDecl(PD);
-  unsigned isObjCMethodParam = Record.readInt();
-  unsigned scopeDepth = Record.readInt();
-  unsigned scopeIndex = Record.readInt();
+
+  uint32_t ParmVarDeclBits = Record.readInt();
+  unsigned isObjCMethodParam = ParmVarDeclBits & 0x1;
+  unsigned scopeDepth = (ParmVarDeclBits >> 1) & 0x7f;
+  unsigned scopeIndex = (ParmVarDeclBits >> 8) & 0xff;
   unsigned declQualifier = Record.readInt();
   if (isObjCMethodParam) {
     assert(scopeDepth == 0);
@@ -1689,9 +1702,9 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
   } else {
     PD->setScopeInfo(scopeDepth, scopeIndex);
   }
-  PD->ParmVarDeclBits.IsKNRPromoted = Record.readInt();
-  PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt();
-  if (Record.readInt()) // hasUninstantiatedDefaultArg.
+  PD->ParmVarDeclBits.IsKNRPromoted = (bool)(ParmVarDeclBits & (1 << 16));
+  PD->ParmVarDeclBits.HasInheritedDefaultArg = (bool)(ParmVarDeclBits & (1 << 17));
+  if ((bool)(ParmVarDeclBits & (1 << 18))) // hasUninstantiatedDefaultArg.
     PD->setUninstantiatedDefaultArg(Record.readExpr());
   PD->ExplicitObjectParameterIntroducerLoc = Record.readSourceLocation();
 
@@ -1790,8 +1803,10 @@ void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
 void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
   VisitNamedDecl(D);
-  D->setInline(Record.readInt());
-  D->setNested(Record.readInt());
+
+  uint32_t NamespaceDeclBits = Record.readInt();
+  D->setInline(NamespaceDeclBits & 0x1);
+  D->setNested(NamespaceDeclBits & 0x2);
   D->LocStart = readSourceLocation();
   D->RBraceLoc = readSourceLocation();
 
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 8a2ea7c7624ceb8..96cdfec14257c98 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -325,16 +325,22 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
     Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
   else
     Record.push_back(0);
-  Record.push_back(D->isInvalidDecl());
-  Record.push_back(D->hasAttrs());
+
+  uint64_t DeclBits = 0;
+  DeclBits = D->isInvalidDecl();
+  DeclBits |= D->hasAttrs() << 1;
+  DeclBits |= D->isImplicit() << 2;
+  DeclBits |= D->isUsed(false) << 3;
+  DeclBits |= D->isReferenced() << 4;
+  DeclBits |= D->isTopLevelDeclInObjCContainer() << 5;
+  assert(D->getAccess() < 4);
+  DeclBits |= D->getAccess() << 6;
+  DeclBits |= (uint64_t)D->getModuleOwnershipKind() << 8;
+  Record.push_back(DeclBits);
+
   if (D->hasAttrs())
     Record.AddAttributes(D->getAttrs());
-  Record.push_back(D->isImplicit());
-  Record.push_back(D->isUsed(false));
-  Record.push_back(D->isReferenced());
-  Record.push_back(D->isTopLevelDeclInObjCContainer());
-  Record.push_back(D->getAccess());
-  Record.push_back((uint64_t)D->getModuleOwnershipKind());
+
   Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
 
   // If this declaration injected a name into a context different from its
@@ -438,12 +444,17 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
   VisitRedeclarable(D);
   VisitTypeDecl(D);
   Record.push_back(D->getIdentifierNamespace());
-  Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
+
+  uint32_t TagDeclBits = 0;
+  assert(D->getTagKind() < 8);
+  TagDeclBits = D->getTagKind();
   if (!isa<CXXRecordDecl>(D))
-    Record.push_back(D->isCompleteDefinition());
-  Record.push_back(D->isEmbeddedInDeclarator());
-  Record.push_back(D->isFreeStanding());
-  Record.push_back(D->isCompleteDefinitionRequired());
+    TagDeclBits |= D->isCompleteDefinition() << 3;
+  TagDeclBits |= D->isEmbeddedInDeclarator() << 4;
+  TagDeclBits |= D->isFreeStanding() << 5;
+  TagDeclBits |= D->isCompleteDefinitionRequired() << 6;
+  Record.push_back(TagDeclBits);
+
   Record.AddSourceRange(D->getBraceRange());
 
   if (D->hasExtInfo()) {
@@ -468,11 +479,17 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
   if (!D->getIntegerTypeSourceInfo())
     Record.AddTypeRef(D->getIntegerType());
   Record.AddTypeRef(D->getPromotionType());
-  Record.push_back(D->getNumPositiveBits());
-  Record.push_back(D->getNumNegativeBits());
-  Record.push_back(D->isScoped());
-  Record.push_back(D->isScopedUsingClassTag());
-  Record.push_back(D->isFixed());
+
+  uint32_t EnumDeclBits = 0;
+  assert(D->getNumPositiveBits() < (2 << 8));
+  EnumDeclBits = D->getNumPositiveBits();
+  assert(D->getNumNegativeBits() < (2 << 8));
+  EnumDeclBits |= D->getNumNegativeBits() << 8;
+  EnumDeclBits |= D->isScoped() << 16;
+  EnumDeclBits |= D->isScopedUsingClassTag() << 17;
+  EnumDeclBits |= D->isFixed() << 18;
+  Record.push_back(EnumDeclBits);
+
   Record.push_back(D->getODRHash());
 
   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
@@ -511,18 +528,23 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
                 "RecordDeclBits");
 
   VisitTagDecl(D);
-  Record.push_back(D->hasFlexibleArrayMember());
-  Record.push_back(D->isAnonymousStructOrUnion());
-  Record.push_back(D->hasObjectMember());
-  Record.push_back(D->hasVolatileMember());
-  Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
-  Record.push_back(D->isNonTrivialToPrimitiveCopy());
-  Record.push_back(D->isNonTrivialToPrimitiveDestroy());
-  Record.push_back(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion());
-  Record.push_back(D->hasNonTrivialToPrimitiveDestructCUnion());
-  Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion());
-  Record.push_back(D->isParamDestroyedInCallee());
-  Record.push_back(D->getArgPassingRestrictions());
+
+  uint32_t RecordDeclBits = 0;
+  RecordDeclBits = D->hasFlexibleArrayMember();
+  RecordDeclBits |= D->isAnonymousStructOrUnion() << 1;
+  RecordDeclBits |= D->hasObjectMember() << 2;
+  RecordDeclBits |= D->hasVolatileMember() << 3;
+  RecordDeclBits |= D->isNonTrivialToPrimitiveDefaultInitialize() << 4;
+  RecordDeclBits |= D->isNonTrivialToPrimitiveCopy() << 5;
+  RecordDeclBits |= D->isNonTrivialToPrimitiveDestroy() << 6;
+  RecordDeclBits |= D->hasNonTrivialToPrimitiveDefaultInitializeCUnion() << 7;
+  RecordDeclBits |= D->hasNonTrivialToPrimitiveDestructCUnion() << 8;
+  RecordDeclBits |= D->hasNonTrivialToPrimitiveCopyCUnion() << 9;
+  RecordDeclBits |= D->isParamDestroyedInCallee() << 10;
+  assert(D->getArgPassingRestrictions() < 4);
+  RecordDeclBits |= D->getArgPassingRestrictions() << 11;
+  Record.push_back(RecordDeclBits);
+
   // Only compute this for C/Objective-C, in C++ this is computed as part
   // of CXXRecordDecl.
   if (!isa<CXXRecordDecl>(D))
@@ -662,28 +684,34 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
 
   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
   // after everything else is written.
-  Record.push_back(
-      static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
-  Record.push_back(D->isInlineSpecified());
-  Record.push_back(D->isInlined());
-  Record.pus...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/69287


More information about the cfe-commits mailing list