]> granicus.if.org Git - clang/commitdiff
Minimize the number and kind of "external definitions" that the PCH
authorDouglas Gregor <dgregor@apple.com>
Wed, 22 Apr 2009 19:09:20 +0000 (19:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 22 Apr 2009 19:09:20 +0000 (19:09 +0000)
file needs to store. CodeGen needs to see these definitions (via
HandleTopLevelDecl), otherwise it won't be able to generate code for
them.

This patch notifies the consumer (e.g., CodeGen) about function
definitions and variable definitions when the corresponding
declarations are deserialized. Hence, we don't eagerly deserialize the
declarations for every variable or function that has a definition in
the PCH file. This gives another 5% speedup for the Carbon-prefixed
"Hello, World!", and brings our PCH statistics down to something far
more reasonable:

*** PCH Statistics:
  13/20693 types read (0.062823%)
  17/59230 declarations read (0.028702%)
  54/44914 identifiers read (0.120230%)
  0/32954 statements read (0.000000%)
  5/6187 macros read (0.080815%)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69820 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/PCHReader.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp

index d5157bc3ce4eb3c8880ba45bf536b20214c0937d..a32be0dd7b490054d9d0418f026116e091ac53f3 100644 (file)
@@ -39,6 +39,7 @@ namespace llvm {
 namespace clang {
 
 class AddrLabelExpr;
+class ASTConsumer;
 class ASTContext;
 class Attr;
 class Decl;
@@ -77,6 +78,9 @@ private:
   /// \brief The AST context into which we'll read the PCH file.
   ASTContext &Context;
 
+  /// \brief The AST consumer.
+  ASTConsumer *Consumer;
+
   /// \brief The bitstream reader from which we'll read the PCH file.
   llvm::BitstreamReader Stream;
 
@@ -198,7 +202,7 @@ public:
   typedef llvm::SmallVector<uint64_t, 64> RecordData;
 
   explicit PCHReader(Preprocessor &PP, ASTContext &Context) 
-    : SemaObj(0), PP(PP), Context(Context), 
+    : SemaObj(0), PP(PP), Context(Context), Consumer(0),
       IdentifierTableData(0), NumStatementsRead(0) { }
 
   ~PCHReader() {}
index 976b98dd11cf01521440f53d70b4fc062d3b6933..c6c34e9749fa9edfa48e417fe7232a4d0788d443 100644 (file)
@@ -377,9 +377,7 @@ void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
 std::pair<uint64_t, uint64_t> 
 PCHDeclReader::VisitDeclContext(DeclContext *DC) {
   uint64_t LexicalOffset = Record[Idx++];
-  uint64_t VisibleOffset = 0;
-  if (DC->getPrimaryContext() == DC)
-    VisibleOffset = Record[Idx++];
+  uint64_t VisibleOffset = Record[Idx++];
   return std::make_pair(LexicalOffset, VisibleOffset);
 }
 
@@ -2317,6 +2315,23 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
   }
   assert(Idx == Record.size());
 
+  if (Consumer) {
+    // If we have deserialized a declaration that has a definition the
+    // AST consumer might need to know about, notify the consumer
+    // about that definition now.
+    if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+      if (Var->isFileVarDecl() && Var->getInit()) {
+        DeclGroupRef DG(Var);
+        Consumer->HandleTopLevelDecl(DG);
+      }
+    } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
+      if (Func->isThisDeclarationADefinition()) {
+        DeclGroupRef DG(Func);
+        Consumer->HandleTopLevelDecl(DG);
+      }
+    }
+  }
+
   return D;
 }
 
@@ -2458,6 +2473,8 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
 }
 
 void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
+  this->Consumer = Consumer;
+
   if (!Consumer)
     return;
 
index 15ee2369dd3bd43f357da9328f22702cf631b8be..b081a2813f9b1794877b3e13b7e1d9e740f4058c 100644 (file)
@@ -574,8 +574,7 @@ void PCHDeclWriter::VisitBlockDecl(BlockDecl *D) {
 void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, 
                                      uint64_t VisibleOffset) {
   Record.push_back(LexicalOffset);
-  if (DC->getPrimaryContext() == DC)
-    Record.push_back(VisibleOffset);
+  Record.push_back(VisibleOffset);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1728,20 +1727,6 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
     // in the PCH file later.
     if (isa<FileScopeAsmDecl>(D))
       ExternalDefinitions.push_back(ID);
-    else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
-      if (// Non-static file-scope variables with initializers or that
-          // are tentative definitions.
-          (Var->isFileVarDecl() &&
-           (Var->getInit() || Var->getStorageClass() == VarDecl::None)) ||
-          // Out-of-line definitions of static data members (C++).
-          (Var->getDeclContext()->isRecord() && 
-           !Var->getLexicalDeclContext()->isRecord() && 
-           Var->getStorageClass() == VarDecl::Static))
-        ExternalDefinitions.push_back(ID);
-    } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
-      if (Func->isThisDeclarationADefinition())
-        ExternalDefinitions.push_back(ID);
-    }
   }
 
   // Exit the declarations block