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

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 16 23:09:31 PDT 2023


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

>From 5a1f32f156801da271486dbb0fd37007adb4901c Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Mon, 16 Oct 2023 16:41:31 +0800
Subject: [PATCH] [NFC] [Serializer] Pack information in serializer

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.
---
 clang/include/clang/AST/Decl.h                |   2 +-
 clang/include/clang/AST/DeclBase.h            |   2 +-
 clang/lib/Serialization/ASTReaderDecl.cpp     | 229 +++++-----
 clang/lib/Serialization/ASTWriter.cpp         |  41 +-
 clang/lib/Serialization/ASTWriterDecl.cpp     | 396 +++++++-----------
 clang/test/Modules/decl-params-determinisim.m |  16 +-
 6 files changed, 330 insertions(+), 356 deletions(-)

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..2a6f142ec0e87c8 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,22 @@ 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 +1057,35 @@ 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 +1588,29 @@ 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 +1622,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 +1630,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 +1695,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 +1708,10 @@ 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 +1810,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();
 
@@ -1926,7 +1948,18 @@ void ASTDeclReader::VisitUnresolvedUsingIfExistsDecl(
 void ASTDeclReader::ReadCXXDefinitionData(
     struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D,
     Decl *LambdaContext, unsigned IndexInLambdaContext) {
-#define FIELD(Name, Width, Merge) Data.Name = Record.readInt();
+
+  uint32_t CXXRecordDeclBits = Record.readInt();
+  uint32_t NextBits = 0;
+
+#define FIELD(Name, Width, Merge)                                              \
+  if (NextBits + Width >= 32) {                                                \
+    CXXRecordDeclBits = Record.readInt();                                      \
+    NextBits = 0;                                                              \
+  }                                                                            \
+  Data.Name = (CXXRecordDeclBits >> NextBits) & ((1 << Width) - 1);            \
+  NextBits += Width;
+
 #include "clang/AST/CXXRecordDeclDefinitionBits.def"
 
   // Note: the caller has deserialized the IsLambda bit already.
@@ -1962,12 +1995,15 @@ void ASTDeclReader::ReadCXXDefinitionData(
     using Capture = LambdaCapture;
 
     auto &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
-    Lambda.DependencyKind = Record.readInt();
-    Lambda.IsGenericLambda = Record.readInt();
-    Lambda.CaptureDefault = Record.readInt();
-    Lambda.NumCaptures = Record.readInt();
+
+    uint32_t LambdaBits = Record.readInt();
+    Lambda.DependencyKind = LambdaBits & 0x3;
+    Lambda.IsGenericLambda = (bool)(LambdaBits & (1 << 2));
+    Lambda.CaptureDefault = (LambdaBits >> 3) & 0x3;
+    Lambda.NumCaptures = (LambdaBits >> 5) & 0x7fff;
+    Lambda.HasKnownInternalLinkage = (bool)(LambdaBits & (1 << 20));
+
     Lambda.NumExplicitCaptures = Record.readInt();
-    Lambda.HasKnownInternalLinkage = Record.readInt();
     Lambda.ManglingNumber = Record.readInt();
     if (unsigned DeviceManglingNumber = Record.readInt())
       Reader.getContext().DeviceLambdaManglingNumbers[D] = DeviceManglingNumber;
@@ -1982,8 +2018,9 @@ void ASTDeclReader::ReadCXXDefinitionData(
     Lambda.MethodTyInfo = readTypeSourceInfo();
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
       SourceLocation Loc = readSourceLocation();
-      bool IsImplicit = Record.readInt();
-      auto Kind = static_cast<LambdaCaptureKind>(Record.readInt());
+      uint32_t CaptureBits = Record.readInt();
+      bool IsImplicit = CaptureBits & 0x1;
+      auto Kind = static_cast<LambdaCaptureKind>(CaptureBits >> 1);
       switch (Kind) {
       case LCK_StarThis:
       case LCK_This:
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 739344b9a128dcf..416b4288a3df892 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5994,11 +5994,23 @@ void ASTRecordWriter::AddCXXCtorInitializers(
 
 void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
   auto &Data = D->data();
+
   Record->push_back(Data.IsLambda);
 
-  #define FIELD(Name, Width, Merge) \
-  Record->push_back(Data.Name);
-  #include "clang/AST/CXXRecordDeclDefinitionBits.def"
+  uint32_t CXXRecordDeclBits = 0;
+  uint32_t NextBits = 0;
+
+#define FIELD(Name, Width, Merge)                                              \
+  if (NextBits + Width >= 32) {                                                \
+    Record->push_back(CXXRecordDeclBits);                                      \
+    CXXRecordDeclBits = 0;                                                     \
+    NextBits = 0;                                                              \
+  }                                                                            \
+  CXXRecordDeclBits |= Data.Name << NextBits;                                  \
+  NextBits += Width;
+#include "clang/AST/CXXRecordDeclDefinitionBits.def"
+
+  Record->push_back(CXXRecordDeclBits);
 
   // getODRHash will compute the ODRHash if it has not been previously computed.
   Record->push_back(D->getODRHash());
@@ -6030,12 +6042,19 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
     AddDeclRef(D->getFirstFriend());
   } else {
     auto &Lambda = D->getLambdaData();
-    Record->push_back(Lambda.DependencyKind);
-    Record->push_back(Lambda.IsGenericLambda);
-    Record->push_back(Lambda.CaptureDefault);
-    Record->push_back(Lambda.NumCaptures);
+
+    uint32_t LambdaBits = 0;
+    assert(Lambda.DependencyKind < 4);
+    LambdaBits = Lambda.DependencyKind;
+    LambdaBits |= Lambda.IsGenericLambda << 2;
+    assert(Lambda.CaptureDefault < 4);
+    LambdaBits |= Lambda.CaptureDefault << 3;
+    assert(Lambda.NumCaptures < (2 << 15));
+    LambdaBits |= Lambda.NumCaptures << 5;
+    LambdaBits |= Lambda.HasKnownInternalLinkage << 20;
+    Record->push_back(LambdaBits);
+
     Record->push_back(Lambda.NumExplicitCaptures);
-    Record->push_back(Lambda.HasKnownInternalLinkage);
     Record->push_back(Lambda.ManglingNumber);
     Record->push_back(D->getDeviceLambdaManglingNumber());
     // The lambda context declaration and index within the context are provided
@@ -6044,8 +6063,10 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
       const LambdaCapture &Capture = Lambda.Captures.front()[I];
       AddSourceLocation(Capture.getLocation());
-      Record->push_back(Capture.isImplicit());
-      Record->push_back(Capture.getCaptureKind());
+      uint32_t CaptureBits = 0;
+      CaptureBits = Capture.isImplicit();
+      CaptureBits |= Capture.getCaptureKind() << 1;
+      Record->push_back(CaptureBits);
       switch (Capture.getCaptureKind()) {
       case LCK_StarThis:
       case LCK_This:
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 8a2ea7c7624ceb8..e2203c2a0f36c8e 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,35 @@ 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.push_back(D->isVirtualAsWritten());
-  Record.push_back(D->isPure());
-  Record.push_back(D->hasInheritedPrototype());
-  Record.push_back(D->hasWrittenPrototype());
-  Record.push_back(D->isDeletedBit());
-  Record.push_back(D->isTrivial());
-  Record.push_back(D->isTrivialForCall());
-  Record.push_back(D->isDefaulted());
-  Record.push_back(D->isExplicitlyDefaulted());
-  Record.push_back(D->isIneligibleOrNotSelected());
-  Record.push_back(D->hasImplicitReturnZero());
-  Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
-  Record.push_back(D->usesSEHTry());
-  Record.push_back(D->hasSkippedBody());
-  Record.push_back(D->isMultiVersion());
-  Record.push_back(D->isLateTemplateParsed());
-  Record.push_back(D->FriendConstraintRefersToEnclosingTemplate());
-  Record.push_back(D->getLinkageInternal());
+  uint64_t FunctionDeclBits = 0;
+
+  assert(static_cast<uint64_t>(D->getStorageClass()) < 0x8);
+  FunctionDeclBits =
+      static_cast<uint64_t>(D->getStorageClass()); // FIXME: stable encoding
+  FunctionDeclBits |= D->isInlineSpecified() << 3;
+  FunctionDeclBits |= D->isInlined() << 4;
+  FunctionDeclBits |= D->isVirtualAsWritten() << 5;
+  FunctionDeclBits |= D->isPure() << 6;
+  FunctionDeclBits |= D->hasInheritedPrototype() << 7;
+  FunctionDeclBits |= D->hasWrittenPrototype() << 8;
+  FunctionDeclBits |= D->isDeletedBit() << 9;
+  FunctionDeclBits |= D->isTrivial() << 10;
+  FunctionDeclBits |= D->isTrivialForCall() << 11;
+  FunctionDeclBits |= D->isDefaulted() << 12;
+  FunctionDeclBits |= D->isExplicitlyDefaulted() << 13;
+  FunctionDeclBits |= D->isIneligibleOrNotSelected() << 14;
+  FunctionDeclBits |= D->hasImplicitReturnZero() << 15;
+  assert(static_cast<uint64_t>(D->getConstexprKind()) < 4);
+  FunctionDeclBits |= static_cast<uint64_t>(D->getConstexprKind()) << 16;
+  FunctionDeclBits |= D->usesSEHTry() << 18;
+  FunctionDeclBits |= D->hasSkippedBody() << 19;
+  FunctionDeclBits |= D->isMultiVersion() << 20;
+  FunctionDeclBits |= D->isLateTemplateParsed() << 21;
+  FunctionDeclBits |= D->FriendConstraintRefersToEnclosingTemplate() << 22;
+  static_assert(sizeof(D->getLinkageInternal()) <= 3);
+  FunctionDeclBits |= D->getLinkageInternal() << 23;
+  Record.push_back(FunctionDeclBits);
+
   Record.AddSourceLocation(D->getEndLoc());
   Record.AddSourceLocation(D->getDefaultLoc());
 
@@ -1043,38 +1072,41 @@ void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
 void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
   VisitRedeclarable(D);
   VisitDeclaratorDecl(D);
-  Record.push_back(D->getStorageClass());
-  Record.push_back(D->getTSCSpec());
-  Record.push_back(D->getInitStyle());
-  Record.push_back(D->isARCPseudoStrong());
+
+  uint32_t VarDeclBits = 0;
+  assert(D->getStorageClass() < 8);
+  VarDeclBits = D->getStorageClass();
+  assert(D->getTSCSpec() < 4);
+  VarDeclBits |= D->getTSCSpec() << 3;
+  assert(D->getInitStyle() < 4);
+  VarDeclBits |= D->getInitStyle() << 5;
+  VarDeclBits |= D->isARCPseudoStrong() << 7;
+
   bool HasDeducedType = false;
   if (!isa<ParmVarDecl>(D)) {
-    Record.push_back(D->isThisDeclarationADemotedDefinition());
-    Record.push_back(D->isExceptionVariable());
-    Record.push_back(D->isNRVOVariable());
-    Record.push_back(D->isCXXForRangeDecl());
-    Record.push_back(D->isObjCForDecl());
-    Record.push_back(D->isInline());
-    Record.push_back(D->isInlineSpecified());
-    Record.push_back(D->isConstexpr());
-    Record.push_back(D->isInitCapture());
-    Record.push_back(D->isPreviousDeclInSameBlockScope());
-    if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
-      Record.push_back(static_cast<unsigned>(IPD->getParameterKind()));
-    else
-      Record.push_back(0);
-    Record.push_back(D->isEscapingByref());
+    VarDeclBits |= D->isThisDeclarationADemotedDefinition() << 8;
+    VarDeclBits |= D->isExceptionVariable() << 9;
+    VarDeclBits |= D->isNRVOVariable() << 10;
+    VarDeclBits |= D->isCXXForRangeDecl() << 11;
+    VarDeclBits |= D->isObjCForDecl() << 12;
+    VarDeclBits |= D->isInline() << 13;
+    VarDeclBits |= D->isInlineSpecified() << 14;
+    VarDeclBits |= D->isConstexpr() << 15;
+    VarDeclBits |= D->isInitCapture() << 16;
+    VarDeclBits |= D->isPreviousDeclInSameBlockScope() << 17;
+
+    if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D)) {
+      assert(IPD->getParameterKind() < 8);
+      VarDeclBits |= IPD->getParameterKind() << 18;
+    }
+
+    VarDeclBits |= D->isEscapingByref() << 21;
     HasDeducedType = D->getType()->getContainedDeducedType();
-    Record.push_back(HasDeducedType);
+    VarDeclBits |= HasDeducedType << 22;
   }
-  Record.push_back(D->getLinkageInternal());
 
-  if (D->hasAttr<BlocksAttr>()) {
-    BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
-    Record.AddStmt(Init.getCopyExpr());
-    if (Init.getCopyExpr())
-      Record.push_back(Init.canThrow());
-  }
+  assert(D->getLinkageInternal() < 8);
+  VarDeclBits |= D->getLinkageInternal() << 23;
 
   bool ModulesCodegen = false;
   if (Writer.WritingModule && D->getStorageDuration() == SD_Static &&
@@ -1089,10 +1121,19 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
           Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
          Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
   }
-  Record.push_back(ModulesCodegen);
+  VarDeclBits |= ModulesCodegen << 26;
+  Record.push_back(VarDeclBits);
+
   if (ModulesCodegen)
     Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
 
+  if (D->hasAttr<BlocksAttr>()) {
+    BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
+    Record.AddStmt(Init.getCopyExpr());
+    if (Init.getCopyExpr())
+      Record.push_back(Init.canThrow());
+  }
+
   enum {
     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
   };
@@ -1144,13 +1185,19 @@ void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
 
 void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
   VisitVarDecl(D);
-  Record.push_back(D->isObjCMethodParameter());
-  Record.push_back(D->getFunctionScopeDepth());
-  Record.push_back(D->getFunctionScopeIndex());
+
+  uint32_t ParmVarDeclBits = 0;
+  ParmVarDeclBits = D->isObjCMethodParameter();
+  assert(D->getFunctionScopeDepth() < (2 << 7));
+  ParmVarDeclBits |= D->getFunctionScopeDepth() << 1;
+  assert(D->getFunctionScopeIndex() < (2 << 8));
+  ParmVarDeclBits |= D->getFunctionScopeIndex() << 8;
+  ParmVarDeclBits |= D->isKNRPromoted() << 16;
+  ParmVarDeclBits |= D->hasInheritedDefaultArg() << 17;
+  ParmVarDeclBits |= D->hasUninstantiatedDefaultArg() << 18;
+  Record.push_back(ParmVarDeclBits);
+
   Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
-  Record.push_back(D->isKNRPromoted());
-  Record.push_back(D->hasInheritedDefaultArg());
-  Record.push_back(D->hasUninstantiatedDefaultArg());
   if (D->hasUninstantiatedDefaultArg())
     Record.AddStmt(D->getUninstantiatedDefaultArg());
   Record.AddSourceLocation(D->getExplicitObjectParamThisLoc());
@@ -1295,8 +1342,12 @@ void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
 void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
   VisitRedeclarable(D);
   VisitNamedDecl(D);
-  Record.push_back(D->isInline());
-  Record.push_back(D->isNested());
+
+  uint32_t NamespaceDeclBits = 0;
+  NamespaceDeclBits = D->isInline();
+  NamespaceDeclBits |= D->isNested() << 1;
+  Record.push_back(NamespaceDeclBits);
+
   Record.AddSourceLocation(D->getBeginLoc());
   Record.AddSourceLocation(D->getRBraceLoc());
 
@@ -2005,14 +2056,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));  // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2038,14 +2082,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));  // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2076,14 +2113,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2094,11 +2124,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
   // TagDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // Tag Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
@@ -2106,11 +2132,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // AddTypeRef
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IntegerType
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getPromotionType
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumPositiveBits
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumNegativeBits
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 19)); // Enum Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
   // DC
@@ -2126,14 +2148,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2144,36 +2159,12 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
   // TagDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // Tag Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
   // RecordDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
-
-  // isNonTrivialToPrimitiveDefaultInitialize
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // isNonTrivialToPrimitiveCopy
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // isNonTrivialToPrimitiveDestroy
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // hasNonTrivialToPrimitiveDefaultInitializeCUnion
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // hasNonTrivialToPrimitiveDestructCUnion
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // hasNonTrivialToPrimitiveCopyCUnion
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // isParamDestroyedInCallee
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
-  // getArgPassingRestrictions
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 13)); // Record Decl Bits
   // ODRHash
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 26));
 
@@ -2190,14 +2181,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2210,20 +2194,11 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
   // VarDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // SClass
-  Abv->Add(BitCodeAbbrevOp(0));                       // TSCSpec
-  Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
-  Abv->Add(BitCodeAbbrevOp(0));                       // Linkage
-  Abv->Add(BitCodeAbbrevOp(0));                       // ModulesCodegen
-  Abv->Add(BitCodeAbbrevOp(0));                       // VarKind (local enum)
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 27)); // Var Decl bits
+  Abv->Add(BitCodeAbbrevOp(0));                          // VarKind (local enum)
   // ParmVarDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
-  Abv->Add(BitCodeAbbrevOp(0));                       // ScopeDepth
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 19)); // Parm Var Decl bits
   Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
-  Abv->Add(BitCodeAbbrevOp(0));                       // KNRPromoted
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
   Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -2238,14 +2213,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2267,14 +2235,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
-  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
-  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
-  Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
-  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2287,25 +2248,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
   // VarDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl
-  Abv->Add(BitCodeAbbrevOp(0));                         // isInline
-  Abv->Add(BitCodeAbbrevOp(0));                         // isInlineSpecified
-  Abv->Add(BitCodeAbbrevOp(0));                         // isConstexpr
-  Abv->Add(BitCodeAbbrevOp(0));                         // isInitCapture
-  Abv->Add(BitCodeAbbrevOp(0));                         // isPrevDeclInSameScope
-  Abv->Add(BitCodeAbbrevOp(0));                         // ImplicitParamKind
-  Abv->Add(BitCodeAbbrevOp(0));                         // EscapingByref
-  Abv->Add(BitCodeAbbrevOp(0));                         // HasDeducedType
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
-  Abv->Add(BitCodeAbbrevOp(0));                         // ModulesCodeGen
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 27)); // Var Decl bits
   Abv->Add(BitCodeAbbrevOp(0));                         // VarKind (local enum)
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -2322,14 +2265,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // DeclContext
   Abv->Add(BitCodeAbbrevOp(0));                         // LexicalDeclContext
-  Abv->Add(BitCodeAbbrevOp(0));                         // Invalid
-  Abv->Add(BitCodeAbbrevOp(0));                         // HasAttrs
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
-  Abv->Add(BitCodeAbbrevOp(0));                         // InObjCContainer
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
@@ -2343,27 +2279,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // TSIType
   // FunctionDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
-  Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto
-  Abv->Add(BitCodeAbbrevOp(1));                         // HasWrittenProto
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // TrivialForCall
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsIneligibleOrNotSelected
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Constexpr
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // MultiVersion
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FriendConstraintRefersToEnclosingTemplate
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 27)); // Function Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LocEnd
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Default
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
diff --git a/clang/test/Modules/decl-params-determinisim.m b/clang/test/Modules/decl-params-determinisim.m
index d7e873bb4938e2c..9eedf0a206423b2 100644
--- a/clang/test/Modules/decl-params-determinisim.m
+++ b/clang/test/Modules/decl-params-determinisim.m
@@ -22,23 +22,23 @@
 /// op13 encodes the anonymous decl number which should be in order.
 // CHECK: <TYPE_FUNCTION_PROTO
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op13=2
+// CHECK-SAME: op11=4024
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op13=3
+// CHECK-SAME: op11=4032
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op13=4
+// CHECK-SAME: op11=4040
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op13=5
+// CHECK-SAME: op11=4048
 
 /// Decl records start at 43
 // CHECK: <DECL_RECORD
-// CHECK-SAME: op13=43
+// CHECK-SAME: op9=4352
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op13=44
+// CHECK-SAME: op9=4360
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op13=45
+// CHECK-SAME: op9=4368
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op13=46
+// CHECK-SAME: op9=4376
 
 //--- headers/a.h
 void f(struct A0 *a0,



More information about the cfe-commits mailing list