Skip to content

Commit 2203a4e

Browse files
committed
[NFC] [Serialization] Improve AST serialization by reordering packed
bits and extract big bits from packed bits Previously I tried to improve the size of .pcm files by introducing packed bits. And I find we can improve it further by reordering the bits. The secret comes from the VBR format. We can find the formal definition of VBR format in the doc of LLVM. The VBR format will be pretty efficicent for small numbers. For example, if we need to pack 8 bits into a value and the stored value is 0xf0, the actual stored value will be 0b000111'110000, which takes 12 bits actually. However, if we changed the order to be 0x0f, then we can store it as 0b001111, which takes 6 bits only now. So we can improve the size by placing bits with lower probability to be 1 in the higher bits and extract bit bigs from the packed bits to make it possible to be optimized by VBR. After this patch, the size of std module becomes to 27.7MB from 28.1MB.
1 parent 0df3200 commit 2203a4e

File tree

4 files changed

+280
-236
lines changed

4 files changed

+280
-236
lines changed

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,18 @@ void ASTDeclReader::Visit(Decl *D) {
584584

585585
void ASTDeclReader::VisitDecl(Decl *D) {
586586
BitsUnpacker DeclBits(Record.readInt());
587+
auto ModuleOwnership =
588+
(Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3);
589+
D->setReferenced(DeclBits.getNextBit());
590+
D->Used = DeclBits.getNextBit();
591+
IsDeclMarkedUsed |= D->Used;
592+
D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2));
593+
D->setImplicit(DeclBits.getNextBit());
587594
bool HasStandaloneLexicalDC = DeclBits.getNextBit();
595+
bool HasAttrs = DeclBits.getNextBit();
596+
D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
597+
D->InvalidDecl = DeclBits.getNextBit();
598+
D->FromASTFile = true;
588599

589600
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
590601
isa<ParmVarDecl, ObjCTypeParamDecl>(D)) {
@@ -623,20 +634,6 @@ void ASTDeclReader::VisitDecl(Decl *D) {
623634
}
624635
D->setLocation(ThisDeclLoc);
625636

626-
D->InvalidDecl = DeclBits.getNextBit();
627-
bool HasAttrs = DeclBits.getNextBit();
628-
D->setImplicit(DeclBits.getNextBit());
629-
D->Used = DeclBits.getNextBit();
630-
IsDeclMarkedUsed |= D->Used;
631-
D->setReferenced(DeclBits.getNextBit());
632-
D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
633-
D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2));
634-
D->FromASTFile = true;
635-
auto ModuleOwnership =
636-
(Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3);
637-
bool ModulePrivate =
638-
(ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
639-
640637
if (HasAttrs) {
641638
AttrVec Attrs;
642639
Record.readAttributes(Attrs);
@@ -647,8 +644,9 @@ void ASTDeclReader::VisitDecl(Decl *D) {
647644

648645
// Determine whether this declaration is part of a (sub)module. If so, it
649646
// may not yet be visible.
647+
bool ModulePrivate =
648+
(ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
650649
if (unsigned SubmoduleID = readSubmoduleID()) {
651-
652650
switch (ModuleOwnership) {
653651
case Decl::ModuleOwnershipKind::Visible:
654652
ModuleOwnership = Decl::ModuleOwnershipKind::VisibleWhenImported;
@@ -1065,9 +1063,11 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
10651063
// after everything else is read.
10661064
BitsUnpacker FunctionDeclBits(Record.readInt());
10671065

1066+
FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
10681067
FD->setStorageClass((StorageClass)FunctionDeclBits.getNextBits(/*Width=*/3));
10691068
FD->setInlineSpecified(FunctionDeclBits.getNextBit());
10701069
FD->setImplicitlyInline(FunctionDeclBits.getNextBit());
1070+
FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
10711071
FD->setVirtualAsWritten(FunctionDeclBits.getNextBit());
10721072
// We defer calling `FunctionDecl::setPure()` here as for methods of
10731073
// `CXXTemplateSpecializationDecl`s, we may not have connected up the
@@ -1081,16 +1081,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
10811081
FD->setDefaulted(FunctionDeclBits.getNextBit());
10821082
FD->setExplicitlyDefaulted(FunctionDeclBits.getNextBit());
10831083
FD->setIneligibleOrNotSelected(FunctionDeclBits.getNextBit());
1084-
FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit());
10851084
FD->setConstexprKind(
10861085
(ConstexprSpecKind)FunctionDeclBits.getNextBits(/*Width=*/2));
1087-
FD->setUsesSEHTry(FunctionDeclBits.getNextBit());
1088-
FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
1086+
FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit());
10891087
FD->setIsMultiVersion(FunctionDeclBits.getNextBit());
10901088
FD->setLateTemplateParsed(FunctionDeclBits.getNextBit());
10911089
FD->setFriendConstraintRefersToEnclosingTemplate(
10921090
FunctionDeclBits.getNextBit());
1093-
FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
1091+
FD->setUsesSEHTry(FunctionDeclBits.getNextBit());
10941092

10951093
FD->EndRangeLoc = readSourceLocation();
10961094
if (FD->isExplicitlyDefaulted())
@@ -1597,6 +1595,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
15971595
VisitDeclaratorDecl(VD);
15981596

15991597
BitsUnpacker VarDeclBits(Record.readInt());
1598+
auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3));
1599+
bool DefGeneratedInModule = VarDeclBits.getNextBit();
16001600
VD->VarDeclBits.SClass = (StorageClass)VarDeclBits.getNextBits(/*Width=*/3);
16011601
VD->VarDeclBits.TSCSpec = VarDeclBits.getNextBits(/*Width=*/2);
16021602
VD->VarDeclBits.InitStyle = VarDeclBits.getNextBits(/*Width=*/2);
@@ -1608,17 +1608,20 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
16081608
VD->NonParmVarDeclBits.ExceptionVar = VarDeclBits.getNextBit();
16091609
VD->NonParmVarDeclBits.NRVOVariable = VarDeclBits.getNextBit();
16101610
VD->NonParmVarDeclBits.CXXForRangeDecl = VarDeclBits.getNextBit();
1611-
VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit();
1611+
16121612
VD->NonParmVarDeclBits.IsInline = VarDeclBits.getNextBit();
16131613
VD->NonParmVarDeclBits.IsInlineSpecified = VarDeclBits.getNextBit();
16141614
VD->NonParmVarDeclBits.IsConstexpr = VarDeclBits.getNextBit();
16151615
VD->NonParmVarDeclBits.IsInitCapture = VarDeclBits.getNextBit();
16161616
VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope =
16171617
VarDeclBits.getNextBit();
1618-
VD->NonParmVarDeclBits.ImplicitParamKind =
1619-
VarDeclBits.getNextBits(/*Width*/ 3);
1618+
16201619
VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit();
16211620
HasDeducedType = VarDeclBits.getNextBit();
1621+
VD->NonParmVarDeclBits.ImplicitParamKind =
1622+
VarDeclBits.getNextBits(/*Width*/ 3);
1623+
1624+
VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit();
16221625
}
16231626

16241627
// If this variable has a deduced type, defer reading that type until we are
@@ -1630,15 +1633,14 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
16301633
VD->setType(Reader.GetType(DeferredTypeID));
16311634
DeferredTypeID = 0;
16321635

1633-
auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3));
16341636
VD->setCachedLinkage(VarLinkage);
16351637

16361638
// Reconstruct the one piece of the IdentifierNamespace that we need.
16371639
if (VD->getStorageClass() == SC_Extern && VarLinkage != Linkage::None &&
16381640
VD->getLexicalDeclContext()->isFunctionOrMethod())
16391641
VD->setLocalExternDecl();
16401642

1641-
if (VarDeclBits.getNextBit()) {
1643+
if (DefGeneratedInModule) {
16421644
Reader.DefinitionSource[VD] =
16431645
Loc.F->Kind == ModuleKind::MK_MainFile ||
16441646
Reader.getContext().getLangOpts().BuildingPCHWithObjectFile;

0 commit comments

Comments
 (0)