Optimize serialized representation of redeclarable declarations for

which there are no redeclarations. This reduced by size of the PCH
file for Cocoa.h by ~650k: ~536k of that was in the new
LOCAL_REDECLARATIONS table, which went from a ridiculous 540k down to
an acceptable 3.5k, while the rest was due to the more compact
abbreviated representation of redeclarable declaration kinds (which no
longer need to store the 'first' declaration ID).

llvm-svn: 146869
This commit is contained in:
Douglas Gregor 2011-12-19 15:27:36 +00:00
parent f4b339decf
commit 9f562c8d9e
7 changed files with 45 additions and 40 deletions

View File

@ -1410,9 +1410,18 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) {
template <typename T>
void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
enum RedeclKind { FirstInFile, PointsToPrevious };
enum RedeclKind { OnlyDeclaration = 0, FirstInFile, PointsToPrevious };
RedeclKind Kind = (RedeclKind)Record[Idx++];
// If this is the only known declaration of this entity, this module file
// has no additional redeclaration information. However, other module
// files might have redeclarations.
if (Kind == OnlyDeclaration) {
if (Reader.PendingDeclChainsKnown.insert(ThisDeclID))
Reader.PendingDeclChains.push_back(ThisDeclID);
return;
}
// Read the first declaration ID, and note that we need to reconstruct
// the redeclaration chain once we hit the top level.
DeclID FirstDeclID = ReadDeclID(Record, Idx);
@ -1422,6 +1431,9 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
switch (Kind) {
case OnlyDeclaration:
llvm_unreachable("only declaration handled above");
case FirstInFile:
if (FirstDecl != D)
D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl);

View File

@ -126,30 +126,6 @@ namespace clang {
};
}
static bool isFirstDeclInFile(Decl *D) {
// FIXME: There must be a better way to abstract Redeclarable<T> into a
// more-general "redeclarable type".
if (TagDecl *Tag = dyn_cast<TagDecl>(D))
return !Tag->getPreviousDeclaration() ||
Tag->getPreviousDeclaration()->isFromASTFile();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return !FD->getPreviousDeclaration() ||
FD->getPreviousDeclaration()->isFromASTFile();
if (VarDecl *VD = dyn_cast<VarDecl>(D))
return !VD->getPreviousDeclaration() ||
VD->getPreviousDeclaration()->isFromASTFile();
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
return !TD->getPreviousDeclaration() ||
TD->getPreviousDeclaration()->isFromASTFile();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return !ID->getPreviousDeclaration() ||
ID->getPreviousDeclaration()->isFromASTFile();
RedeclarableTemplateDecl *RTD = cast<RedeclarableTemplateDecl>(D);
return !RTD->getPreviousDeclaration() ||
RTD->getPreviousDeclaration()->isFromASTFile();
}
void ASTDeclWriter::Visit(Decl *D) {
DeclVisitor<ASTDeclWriter>::Visit(D);
@ -212,7 +188,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
isFirstDeclInFile(D) &&
D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@ -262,7 +238,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
isFirstDeclInFile(D) &&
D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@ -286,7 +262,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
isFirstDeclInFile(D) &&
D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@ -732,7 +708,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
!D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
!D->hasExtInfo() &&
isFirstDeclInFile(D) &&
D->RedeclLink.getPointer() == D &&
!D->hasCXXDirectInitializer() &&
D->getInit() == 0 &&
!isa<ParmVarDecl>(D) &&
@ -1298,7 +1274,13 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
template <typename T>
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
enum { FirstInFile, PointsToPrevious };
enum { OnlyDeclaration = 0, FirstInFile, PointsToPrevious };
if (D->RedeclLink.getPointer() == D) {
// This is the only declaration.
Record.push_back(OnlyDeclaration);
return;
}
T *First = D->getFirstDeclaration();
if (!D->getPreviousDeclaration() ||
D->getPreviousDeclaration()->isFromASTFile()) {
@ -1399,8 +1381,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // First in file
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@ -1447,8 +1428,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // First in file
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@ -1489,8 +1469,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // First in file
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@ -1540,8 +1519,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // First in file
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@ -1569,8 +1547,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
// Redeclarable
Abv->Add(BitCodeAbbrevOp(0)); // First in file
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext

View File

@ -1,4 +1,7 @@
__import_module__ redecl_merge_left;
__import_module__ redecl_merge_right;
@class B;
@class A;

View File

@ -4,4 +4,8 @@ __import_module__ redecl_merge_top;
@class A;
@interface B
@end
@class A;

View File

@ -7,3 +7,5 @@ __import_module__ redecl_merge_top;
- (Super*)init;
@end
@class B;

View File

@ -3,3 +3,5 @@
@class A;
@class A;
@class B;

View File

@ -14,8 +14,13 @@ void f(A *a) {
@class A;
@class B;
__import_module__ redecl_merge_bottom;
@implementation B
@end
void g(A *a) {
[a init];
}