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).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146869 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-12-19 15:27:36 +00:00
Родитель 68d7bb97fc
Коммит ecb19382e1
7 изменённых файлов: 45 добавлений и 40 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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];
}