forked from OSchip/llvm-project
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:
parent
f4b339decf
commit
9f562c8d9e
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue