]> granicus.if.org Git - clang/commitdiff
Optimize serialized representation of redeclarable declarations for
authorDouglas Gregor <dgregor@apple.com>
Mon, 19 Dec 2011 15:27:36 +0000 (15:27 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 19 Dec 2011 15:27:36 +0000 (15:27 +0000)
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

lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/Modules/Inputs/redecl-merge-bottom.h
test/Modules/Inputs/redecl-merge-left.h
test/Modules/Inputs/redecl-merge-right.h
test/Modules/Inputs/redecl-merge-top.h
test/Modules/redecl-merge.m

index d538d6ebb6e76da197aaa8a7b17c2ea778769342..3e08d99ae6061aa3d491adc761787ab3145f4897 100644 (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);
index 4e9a315d22d48f210aac440b10989ae7c3b798ee..bb4359a54b16f5c0c074baec2dfe8decfe5624a0 100644 (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
index e45e0dea0477ec1f1d3672533e6dc31b0257e357..198bde3e5faa49658392ed1297f26b2159d96c80 100644 (file)
@@ -1,4 +1,7 @@
 __import_module__ redecl_merge_left;
 __import_module__ redecl_merge_right;
 
+@class B;
+
 @class A;
+
index 085892234818cd04796988109c5d45c4fef7335a..048b3e6c2def9fc0558c58c58ab0adc85f677b3a 100644 (file)
@@ -4,4 +4,8 @@ __import_module__ redecl_merge_top;
 
 @class A;
 
+@interface B
+@end
+
 @class A;
+
index 266146c9953e8fff73a29738377314daa056bfe8..d8fd45f2b94c8e2e138ac468a6334514456e9055 100644 (file)
@@ -7,3 +7,5 @@ __import_module__ redecl_merge_top;
 - (Super*)init;
 @end
 
+@class B;
+
index 886436cdda8670d59a7aec93dbb4b0055ba7e683..68dae5058e2451a6c7ab164c84c0434cdf30dea0 100644 (file)
@@ -3,3 +3,5 @@
 @class A;
 
 @class A;
+
+@class B;
index d62d504868c510c65490763ae9e8df1decb15ecd..fe25044166335f505e880dd35669356b668965e2 100644 (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];
 }