[cfe-commits] r70097 - in /cfe/trunk: include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHReader.h include/clang/Frontend/PCHWriter.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp

Douglas Gregor dgregor at apple.com
Sat Apr 25 17:07:37 PDT 2009


Author: dgregor
Date: Sat Apr 25 19:07:37 2009
New Revision: 70097

URL: http://llvm.org/viewvc/llvm-project?rev=70097&view=rev
Log:
Don't read all of the records in the PCH file's preprocessor block,
most of which are ignored. Instead, move the __COUNTER__ value out to
a PCH-level record (since it is handled eagerly) and move the header
file information into the SourceManager block (which is also,
currently, loaded eagerly).

This results in another 17% performance improvement in the
Cocoa-prefixed "Hello, World" with PCH.


Modified:
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Frontend/PCHReader.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=70097&r1=70096&r2=70097&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Sat Apr 25 19:07:37 2009
@@ -169,7 +169,11 @@
       SELECTOR_OFFSETS = 12,
 
       /// \brief Record code for the Objective-C method pool,
-      METHOD_POOL = 13
+      METHOD_POOL = 13,
+
+      /// \brief The value of the next __COUNTER__ to dispense.
+      /// [PP_COUNTER_VALUE, Val]
+      PP_COUNTER_VALUE = 14
     };
 
     /// \brief Record types used within a source manager block.
@@ -189,7 +193,10 @@
       SM_SLOC_INSTANTIATION_ENTRY = 4,
       /// \brief Describes the SourceManager's line table, with
       /// information about #line directives.
-      SM_LINE_TABLE = 5
+      SM_LINE_TABLE = 5,
+      /// \brief Describes one header file info [isImport, DirInfo, NumIncludes]
+      /// ControllingMacro is optional.
+      SM_HEADER_FILE_INFO = 6
     };
     
     /// \brief Record types used within a preprocessor block.
@@ -208,15 +215,7 @@
       
       /// \brief Describes one token.
       /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
-      PP_TOKEN = 3,
-      
-      /// \brief The value of the next __COUNTER__ to dispense.
-      /// [PP_COUNTER_VALUE, Val]
-      PP_COUNTER_VALUE = 4,
-      
-      /// \brief Describes one header file info [isImport, DirInfo, NumIncludes]
-      /// ControlloingMacro is optional.
-      PP_HEADER_FILE_INFO = 5
+      PP_TOKEN = 3
     };
 
     /// \defgroup PCHAST Precompiled header AST constants

Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=70097&r1=70096&r2=70097&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Sat Apr 25 19:07:37 2009
@@ -245,12 +245,11 @@
   /// Objective-C protocols.
   llvm::SmallVector<Decl *, 16> InterestingDecls;
 
-  PCHReadResult ReadPCHBlock(uint64_t &PreprocessorBlockOffset);
+  PCHReadResult ReadPCHBlock();
   bool CheckPredefinesBuffer(const char *PCHPredef, 
                              unsigned PCHPredefLen,
                              FileID PCHBufferID);
   PCHReadResult ReadSourceManagerBlock();
-  bool ReadPreprocessorBlock();
   
   bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
   QualType ReadTypeRecord(uint64_t Offset);

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=70097&r1=70096&r2=70097&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Sat Apr 25 19:07:37 2009
@@ -156,7 +156,8 @@
 
   void WriteTargetTriple(const TargetInfo &Target);
   void WriteLanguageOptions(const LangOptions &LangOpts);
-  void WriteSourceManagerBlock(SourceManager &SourceMgr);
+  void WriteSourceManagerBlock(SourceManager &SourceMgr, 
+                               const Preprocessor &PP);
   void WritePreprocessor(const Preprocessor &PP);
   void WriteType(const Type *T);
   void WriteTypesBlock(ASTContext &Context);

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=70097&r1=70096&r2=70097&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sat Apr 25 19:07:37 2009
@@ -1473,6 +1473,7 @@
 
   SourceManager &SourceMgr = Context.getSourceManager();
   RecordData Record;
+  unsigned NumHeaderInfos = 0;
   while (true) {
     unsigned Code = Stream.ReadCode();
     if (Code == llvm::bitc::END_BLOCK) {
@@ -1557,6 +1558,16 @@
       if (ParseLineTable(SourceMgr, Record))
         return Failure;
       break;
+
+    case pch::SM_HEADER_FILE_INFO: {
+      HeaderFileInfo HFI;
+      HFI.isImport = Record[0];
+      HFI.DirInfo = Record[1];
+      HFI.NumIncludes = Record[2];
+      HFI.ControllingMacroID = Record[3];
+      PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
+      break;
+    }
     }
   }
 }
@@ -1597,10 +1608,6 @@
     pch::PreprocessorRecordTypes RecType =
       (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
     switch (RecType) {
-    case pch::PP_COUNTER_VALUE:
-      // Skip this record.
-      break;
-
     case pch::PP_MACRO_OBJECT_LIKE:
     case pch::PP_MACRO_FUNCTION_LIKE: {
       // If we already have a macro, that means that we've hit the end
@@ -1663,70 +1670,12 @@
       Macro->AddTokenToBody(Tok);
       break;
     }
-    case pch::PP_HEADER_FILE_INFO:
-      break; // Already processed by ReadPreprocessorBlock().
   }
   }
 }
 
-bool PCHReader::ReadPreprocessorBlock() {
-  if (Stream.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID))
-    return Error("Malformed preprocessor block record");
-  
-  RecordData Record;
-  unsigned NumHeaderInfos = 0;
-  while (true) {
-    unsigned Code = Stream.ReadCode();
-    switch (Code) {
-    case llvm::bitc::END_BLOCK:
-      if (Stream.ReadBlockEnd())
-        return Error("Error at end of preprocessor block");
-      return false;
-    
-    case llvm::bitc::ENTER_SUBBLOCK:
-      // No known subblocks, always skip them.
-      Stream.ReadSubBlockID();
-      if (Stream.SkipBlock())
-        return Error("Malformed block record");
-      continue;
-    
-    case llvm::bitc::DEFINE_ABBREV:
-      Stream.ReadAbbrevRecord();
-      continue;
-    default: break;
-    }
-    
-    // Read a record.
-    Record.clear();
-    pch::PreprocessorRecordTypes RecType =
-      (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
-    switch (RecType) {
-    default:  // Default behavior: ignore unknown records.
-      break;
-    case pch::PP_COUNTER_VALUE:
-      if (!Record.empty())
-        PP.setCounterValue(Record[0]);
-      break;
-
-    case pch::PP_MACRO_OBJECT_LIKE:
-    case pch::PP_MACRO_FUNCTION_LIKE:
-    case pch::PP_TOKEN:
-      break;
-    case pch::PP_HEADER_FILE_INFO: {
-      HeaderFileInfo HFI;
-      HFI.isImport = Record[0];
-      HFI.DirInfo = Record[1];
-      HFI.NumIncludes = Record[2];
-      HFI.ControllingMacroID = Record[3];
-      PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
-      break;
-    }
-    }
-  }
-}
-
 PCHReader::PCHReadResult 
-PCHReader::ReadPCHBlock(uint64_t &PreprocessorBlockOffset) {
+PCHReader::ReadPCHBlock() {
   if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
     Error("Malformed block record");
     return Failure;
@@ -1757,13 +1706,6 @@
         break;
 
       case pch::PREPROCESSOR_BLOCK_ID:
-        // Skip the preprocessor block for now, but remember where it is.  We
-        // want to read it in after the identifier table.
-        if (PreprocessorBlockOffset) {
-          Error("Multiple preprocessor blocks found.");
-          return Failure;
-        }
-        PreprocessorBlockOffset = Stream.GetCurrentBitNo();
         if (Stream.SkipBlock()) {
           Error("Malformed block record");
           return Failure;
@@ -1907,6 +1849,11 @@
                         PCHMethodPoolLookupTrait(*this));
       TotalSelectorsInMethodPool = Record[1];
       break;
+
+    case pch::PP_COUNTER_VALUE:
+      if (!Record.empty())
+        PP.setCounterValue(Record[0]);
+      break;
     }
   }
   Error("Premature end of bitstream");
@@ -1938,10 +1885,6 @@
     return IgnorePCH;
   }
 
-  // We expect a number of well-defined blocks, though we don't necessarily
-  // need to understand them all.
-  uint64_t PreprocessorBlockOffset = 0;
-  
   while (!Stream.AtEndOfStream()) {
     unsigned Code = Stream.ReadCode();
     
@@ -1961,7 +1904,7 @@
       }
       break;
     case pch::PCH_BLOCK_ID:
-      switch (ReadPCHBlock(PreprocessorBlockOffset)) {
+      switch (ReadPCHBlock()) {
       case Success:
         break;
 
@@ -2036,15 +1979,6 @@
   if (unsigned FastEnum 
         = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
     Context.setObjCFastEnumerationStateType(GetType(FastEnum));
-  // If we saw the preprocessor block, read it now.
-  if (PreprocessorBlockOffset) {
-    SavedStreamPosition SavedPos(Stream);
-    Stream.JumpToBit(PreprocessorBlockOffset);
-    if (ReadPreprocessorBlock()) {
-      Error("Malformed preprocessor block");
-      return Failure;
-    }
-  }
 
   return Success;
 }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=70097&r1=70096&r2=70097&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sat Apr 25 19:07:37 2009
@@ -1359,7 +1359,8 @@
 /// entries for files that we actually need. In the common case (no
 /// errors), we probably won't have to create file entries for any of
 /// the files in the AST.
-void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
+void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
+                                        const Preprocessor &PP) {
   // Enter the source manager block.
   Stream.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
 
@@ -1481,6 +1482,22 @@
     }
   }
 
+  // Loop over all the header files.
+  HeaderSearch &HS = PP.getHeaderSearchInfo();  
+  for (HeaderSearch::header_file_iterator I = HS.header_file_begin(), 
+                                          E = HS.header_file_end();
+       I != E; ++I) {
+    Record.push_back(I->isImport);
+    Record.push_back(I->DirInfo);
+    Record.push_back(I->NumIncludes);
+    if (I->ControllingMacro)
+      AddIdentifierRef(I->ControllingMacro, Record);
+    else
+      Record.push_back(0);
+    Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
+    Record.clear();
+  }
+
   Stream.ExitBlock();
 }
 
@@ -1488,14 +1505,6 @@
 /// preprocessor.
 ///
 void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
-  // Enter the preprocessor block.
-  Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
-  
-  // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
-  // FIXME: use diagnostics subsystem for localization etc.
-  if (PP.SawDateOrTime())
-    fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
-  
   RecordData Record;
 
   // If the preprocessor __COUNTER__ value has been bumped, remember it.
@@ -1503,8 +1512,16 @@
     Record.push_back(PP.getCounterValue());
     Stream.EmitRecord(pch::PP_COUNTER_VALUE, Record);
     Record.clear();
-  }  
+  }
+
+  // Enter the preprocessor block.
+  Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
   
+  // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
+  // FIXME: use diagnostics subsystem for localization etc.
+  if (PP.SawDateOrTime())
+    fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
+    
   // Loop over all the macro definitions that are live at the end of the file,
   // emitting each to the PP section.
   for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
@@ -1564,22 +1581,6 @@
     }
     ++NumMacros;
   }
-
-  // Loop over all the header files.
-  HeaderSearch &HS = PP.getHeaderSearchInfo();  
-  for (HeaderSearch::header_file_iterator I = HS.header_file_begin(), 
-                                          E = HS.header_file_end();
-       I != E; ++I) {
-    Record.push_back(I->isImport);
-    Record.push_back(I->DirInfo);
-    Record.push_back(I->NumIncludes);
-    if (I->ControllingMacro)
-      AddIdentifierRef(I->ControllingMacro, Record);
-    else
-      Record.push_back(0);
-    Stream.EmitRecord(pch::PP_HEADER_FILE_INFO, Record);
-    Record.clear();
-  }
   Stream.ExitBlock();
 }
 
@@ -2365,7 +2366,7 @@
   Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
   WriteTargetTriple(Context.Target);
   WriteLanguageOptions(Context.getLangOptions());
-  WriteSourceManagerBlock(Context.getSourceManager());
+  WriteSourceManagerBlock(Context.getSourceManager(), PP);
   WritePreprocessor(PP);
   WriteTypesBlock(Context);
   WriteDeclsBlock(Context);





More information about the cfe-commits mailing list