Introduce additional abbreviations into the AST writer for

DeclRefExprs, IntegerLiterals, and others, reducing Cocoa PCH size by
~1% and C++ header size by ~2.5%. From Jonathan Turner!

llvm-svn: 132528
This commit is contained in:
Douglas Gregor
2011-06-03 02:27:19 +00:00
parent c71224e29f
commit 03412ba003
5 changed files with 198 additions and 13 deletions

View File

@@ -514,6 +514,9 @@ namespace clang {
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 100;
/// \brief The number of allowed abbreviations in bits
const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
/// \brief Record codes for each kind of type.
///
/// These constants describe the type records that can occur within a

View File

@@ -342,6 +342,12 @@ private:
unsigned DeclContextLexicalAbbrev;
unsigned DeclContextVisibleLookupAbbrev;
unsigned UpdateVisibleAbbrev;
unsigned DeclRefExprAbbrev;
unsigned CharacterLiteralAbbrev;
unsigned DeclRecordAbbrev;
unsigned IntegerLiteralAbbrev;
unsigned EnumConstantDeclAbbrev;
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
@@ -569,7 +575,12 @@ public:
unsigned getOpaqueValueID(OpaqueValueExpr *e);
unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
unsigned getEnumConstantDeclAbbrev() const { return EnumConstantDeclAbbrev; }
bool hasChain() const { return Chain; }
// ASTDeserializationListener implementation

View File

@@ -889,13 +889,14 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DECL_INDIRECTFIELD);
RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK);
// Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
BLOCK(PREPROCESSOR_DETAIL_BLOCK);
RECORD(PPD_MACRO_INSTANTIATION);
RECORD(PPD_MACRO_DEFINITION);
RECORD(PPD_INCLUSION_DIRECTIVE);
// Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
#undef RECORD
#undef BLOCK
Stream.ExitBlock();
@@ -2700,8 +2701,13 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID),
CollectedStmts(&StmtsToEmit),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
NumVisibleDeclContexts(0), FirstCXXBaseSpecifiersID(1),
NextCXXBaseSpecifiersID(1)
NumVisibleDeclContexts(0),
FirstCXXBaseSpecifiersID(1), NextCXXBaseSpecifiersID(1),
ParmVarDeclAbbrev(0), DeclContextLexicalAbbrev(0),
DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0),
DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
DeclRecordAbbrev(0), IntegerLiteralAbbrev(0),
EnumConstantDeclAbbrev(0)
{
}
@@ -2867,7 +2873,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// Keep writing types and declarations until all types and
// declarations have been written.
Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3);
Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
WriteDeclsBlockAbbrevs();
while (!DeclTypesToEmit.empty()) {
DeclOrType DOT = DeclTypesToEmit.front();
@@ -3097,7 +3103,7 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
}
Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3);
Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
WriteDeclsBlockAbbrevs();
for (DeclsToRewriteTy::iterator
I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I)
@@ -3209,7 +3215,7 @@ void ASTWriter::WriteDeclUpdatesBlocks() {
return;
RecordData OffsetsRecord;
Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, 3);
Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
for (DeclUpdateMap::iterator
I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
const Decl *D = I->first;

View File

@@ -213,6 +213,21 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
Record.push_back(D->hasFlexibleArrayMember());
Record.push_back(D->isAnonymousStructOrUnion());
Record.push_back(D->hasObjectMember());
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
D->getPCHLevel() == 0 &&
!D->hasExtInfo() &&
D->RedeclLink.getNext() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
!CXXRecordDecl::classofKind(D->getKind()) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclRecordAbbrev();
Code = serialization::DECL_RECORD;
}
@@ -227,6 +242,20 @@ void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (D->getInitExpr())
Writer.AddStmt(D->getInitExpr());
Writer.AddAPSInt(D->getInitVal(), Record);
if (!D->getInitExpr() &&
!D->isInvalidDecl() &&
!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
D->getPCHLevel() == 0 &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
D->getInitVal().getBitWidth() == 32
)
AbbrevToUse = Writer.getEnumConstantDeclAbbrev();
Code = serialization::DECL_ENUM_CONSTANT;
}
@@ -1149,10 +1178,12 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
void ASTWriter::WriteDeclsBlockAbbrevs() {
using namespace llvm;
// Abbreviation for DECL_PARM_VAR.
BitCodeAbbrev *Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
BitCodeAbbrev *Abv;
// Abbreviation for DECL_ENUM_CONSTANT
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM_CONSTANT));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1164,7 +1195,71 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
Abv->Add(BitCodeAbbrevOp(0)); // PCH level
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
// ValueDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
// EnumConstantDecl
Abv->Add(BitCodeAbbrevOp(0)); // getInitExpr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //isUnsigned
Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
EnumConstantDeclAbbrev = Stream.EmitAbbrev(Abv);
// Abbreviation for DECL_RECORD
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
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(AS_none)); // C++ AccessSpecifier
Abv->Add(BitCodeAbbrevOp(0)); // PCH level
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
// TypeDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDefinition
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypedefNameAnonDecl
// RecordDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
// DC
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
DeclRecordAbbrev = Stream.EmitAbbrev(Abv);
// Abbreviation for DECL_PARM_VAR
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
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(AS_none)); // C++ AccessSpecifier
Abv->Add(BitCodeAbbrevOp(0)); // PCH level
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1193,9 +1288,61 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // KNRPromoted
Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedDefaultArg
Abv->Add(BitCodeAbbrevOp(0)); // HasUninstantiatedDefaultArg
ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
// Abbreviation for EXPR_DECL_REF
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
//Stmt
//Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
//DeclRefExpr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
// Abbreviation for EXPR_INTEGER_LITERAL
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
//Stmt
//Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
//Integer Literal
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
IntegerLiteralAbbrev = Stream.EmitAbbrev(Abv);
// Abbreviation for EXPR_CHARACTER_LITERAL
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
//Stmt
//Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
//CharacterLiteral
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsWide
CharacterLiteralAbbrev = Stream.EmitAbbrev(Abv);
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));

View File

@@ -30,6 +30,7 @@ namespace clang {
public:
serialization::StmtCode Code;
unsigned AbbrevToUse;
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
: Writer(Writer), Record(Record) { }
@@ -392,6 +393,14 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
Record.push_back(NumTemplateArgs);
}
DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
if ((!E->hasExplicitTemplateArgs()) && (!E->hasQualifier()) &&
(E->getDecl() == E->getFoundDecl()) &&
nk == DeclarationName::Identifier) {
AbbrevToUse = Writer.getDeclRefExprAbbrev();
}
if (E->hasQualifier())
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
@@ -411,6 +420,11 @@ void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
VisitExpr(E);
Writer.AddSourceLocation(E->getLocation(), Record);
Writer.AddAPInt(E->getValue(), Record);
if (E->getValue().getBitWidth() == 32) {
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
}
Code = serialization::EXPR_INTEGER_LITERAL;
}
@@ -449,6 +463,9 @@ void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
Record.push_back(E->getValue());
Writer.AddSourceLocation(E->getLocation(), Record);
Record.push_back(E->isWide());
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
Code = serialization::EXPR_CHARACTER_LITERAL;
}
@@ -1460,6 +1477,7 @@ void ASTWriter::WriteSubStmt(Stmt *S) {
CollectedStmts = &SubStmts;
Writer.Code = serialization::STMT_NULL_PTR;
Writer.AbbrevToUse = 0;
Writer.Visit(S);
#ifndef NDEBUG
@@ -1481,7 +1499,7 @@ void ASTWriter::WriteSubStmt(Stmt *S) {
while (!SubStmts.empty())
WriteSubStmt(SubStmts.pop_back_val());
Stream.EmitRecord(Writer.Code, Record);
Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
}
/// \brief Flush all of the statements that have been added to the