[cfe-commits] r143238 - in /cfe/trunk: include/clang/Serialization/ASTBitCodes.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h include/clang/Serialization/Module.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp lib/Serialization/Module.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Oct 28 15:54:21 PDT 2011


Author: akirtzidis
Date: Fri Oct 28 17:54:21 2011
New Revision: 143238

URL: http://llvm.org/viewvc/llvm-project?rev=143238&view=rev
Log:
[PCH] Keep track of file-level declarations that are contained by files.

Introduce a FILE_SORTED_DECLS [de]serialization record that contains
a file sorted array of file-level DeclIDs in a PCH/Module.
The rationale is to allow "targeted" deserialization of decls inside
a range of a source file.

Cocoa PCH increased by 0.8%
Difference of creation time for Cocoa PCH is below the noise level.

Modified:
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/include/clang/Serialization/Module.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/Serialization/Module.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Oct 28 17:54:21 2011
@@ -436,7 +436,10 @@
 
       /// \brief Record code for ObjC categories in a module that are chained to
       /// an interface.
-      OBJC_CHAINED_CATEGORIES
+      OBJC_CHAINED_CATEGORIES,
+
+      /// \brief Record code for a file sorted array of DeclIDs in a module.
+      FILE_SORTED_DECLS
     };
 
     /// \brief Record types used within a source manager block.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Oct 28 17:54:21 2011
@@ -296,6 +296,9 @@
   /// \brief Declarations that have been replaced in a later file in the chain.
   DeclReplacementMap ReplacedDecls;
 
+  /// \brief Map from a FileID to the file-level declarations that it contains.
+  llvm::DenseMap<FileID, ArrayRef<serialization::DeclID> > FileDeclIDs;
+
   // Updates for visible decls can occur for other contexts than just the
   // TU, and when we read those update records, the actual context will not
   // be available yet (unless it's the TU), so have this pending map using the

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Oct 28 17:54:21 2011
@@ -59,6 +59,8 @@
 class TargetInfo;
 class VersionTuple;
 
+namespace SrcMgr { class SLocEntry; }
+
 /// \brief Writes an AST file containing the contents of a translation unit.
 ///
 /// The ASTWriter class produces a bitstream containing the serialized
@@ -144,6 +146,25 @@
   /// the declaration's ID.
   std::vector<serialization::DeclOffset> DeclOffsets;
 
+  /// \brief Vector of pairs of raw location/DeclID.
+  typedef SmallVector<std::pair<unsigned, serialization::DeclID>, 64>
+    LocDeclIDsTy;
+  struct DeclIDInFileInfo {
+    LocDeclIDsTy DeclIDs;
+    /// \brief Set when the DeclIDs vectors from all files are joined, this
+    /// indicates the index that this particular vector has in the global one.
+    unsigned FirstDeclIndex;
+  };
+  typedef llvm::DenseMap<const SrcMgr::SLocEntry *,
+                         DeclIDInFileInfo *> FileDeclIDsTy;
+
+  /// \brief Map from file SLocEntries to info about the file-level declarations
+  /// that it contains.
+  FileDeclIDsTy FileDeclIDs;
+
+  void associateDeclWithFile(const Decl *D, serialization::DeclID,
+                             SourceLocation FileLoc);
+
   /// \brief The first ID number we can use for our own types.
   serialization::TypeID FirstTypeID;
 
@@ -354,6 +375,7 @@
   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
   void WriteTypeDeclOffsets();
+  void WriteFileDeclIDsMap();
   void WriteSelectors(Sema &SemaRef);
   void WriteReferencedSelectorsPool(Sema &SemaRef);
   void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
@@ -393,6 +415,7 @@
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
   ASTWriter(llvm::BitstreamWriter &Stream);
+  ~ASTWriter();
                     
   /// \brief Write a precompiled header for the given semantic analysis.
   ///

Modified: cfe/trunk/include/clang/Serialization/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/Module.h (original)
+++ cfe/trunk/include/clang/Serialization/Module.h Fri Oct 28 17:54:21 2011
@@ -271,6 +271,9 @@
   /// Key is the ID of the interface.
   /// Value is a pair of linked category DeclIDs (head category, tail category).
   ChainedObjCCategoriesMap ChainedObjCCategories;
+
+  /// \brief Array of file-level DeclIDs sorted by file.
+  const serialization::DeclID *FileSortedDecls;
   
   // === Types ===
   

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Oct 28 17:54:21 2011
@@ -1134,6 +1134,13 @@
     FileInfo.NumCreatedFIDs = Record[6];
     if (Record[3])
       FileInfo.setHasLineDirectives();
+
+    const DeclID *FirstDecl = F->FileSortedDecls + Record[7];
+    unsigned NumFileDecls = Record[8];
+    if (NumFileDecls) {
+      assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
+      FileDeclIDs[FID] = llvm::makeArrayRef(FirstDecl, NumFileDecls);
+    }
     
     break;
   }
@@ -1960,6 +1967,10 @@
       if (!Record.empty() && Listener)
         Listener->ReadCounter(Record[0]);
       break;
+      
+    case FILE_SORTED_DECLS:
+      F.FileSortedDecls = (const DeclID *)BlobStart;
+      break;
 
     case SOURCE_LOCATION_OFFSETS: {
       F.SLocEntryOffsets = (const uint32_t *)BlobStart;

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Oct 28 17:54:21 2011
@@ -1172,6 +1172,8 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
   return Stream.EmitAbbrev(Abbrev);
 }
@@ -1445,6 +1447,15 @@
         Record.push_back(Content->OrigEntry->getModificationTime());
 
         Record.push_back(File.NumCreatedFIDs);
+        
+        FileDeclIDsTy::iterator FDI = FileDeclIDs.find(SLoc);
+        if (FDI != FileDeclIDs.end()) {
+          Record.push_back(FDI->second->FirstDeclIndex);
+          Record.push_back(FDI->second->DeclIDs.size());
+        } else {
+          Record.push_back(0);
+          Record.push_back(0);
+        }
 
         // Turn the file name into an absolute path, if it isn't already.
         const char *Filename = Content->OrigEntry->getName();
@@ -1972,6 +1983,29 @@
   Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets));
 }
 
+void ASTWriter::WriteFileDeclIDsMap() {
+  using namespace llvm;
+  RecordData Record;
+
+  // Join the vectors of DeclIDs from all files.
+  SmallVector<DeclID, 256> FileSortedIDs;
+  for (FileDeclIDsTy::iterator
+         FI = FileDeclIDs.begin(), FE = FileDeclIDs.end(); FI != FE; ++FI) {
+    DeclIDInFileInfo &Info = *FI->second;
+    Info.FirstDeclIndex = FileSortedIDs.size();
+    for (LocDeclIDsTy::iterator
+           DI = Info.DeclIDs.begin(), DE = Info.DeclIDs.end(); DI != DE; ++DI)
+      FileSortedIDs.push_back(DI->second);
+  }
+
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+  Record.push_back(FILE_SORTED_DECLS);
+  Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs));
+}
+
 //===----------------------------------------------------------------------===//
 // Global Method Pool and Selector Serialization
 //===----------------------------------------------------------------------===//
@@ -2732,6 +2766,12 @@
 {
 }
 
+ASTWriter::~ASTWriter() {
+  for (FileDeclIDsTy::iterator
+         I = FileDeclIDs.begin(), E = FileDeclIDs.end(); I != E; ++I)
+    delete I->second;
+}
+
 void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
                          const std::string &OutputFile,
                          bool IsModule, StringRef isysroot) {
@@ -2910,49 +2950,6 @@
   WriteLanguageOptions(Context.getLangOptions());
   if (StatCalls && isysroot.empty())
     WriteStatCache(*StatCalls);
-  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
-  
-  if (Chain) {
-    // Write the mapping information describing our module dependencies and how
-    // each of those modules were mapped into our own offset/ID space, so that
-    // the reader can build the appropriate mapping to its own offset/ID space.
-    // The map consists solely of a blob with the following format:
-    // *(module-name-len:i16 module-name:len*i8
-    //   source-location-offset:i32
-    //   identifier-id:i32
-    //   preprocessed-entity-id:i32
-    //   macro-definition-id:i32
-    //   selector-id:i32
-    //   declaration-id:i32
-    //   c++-base-specifiers-id:i32
-    //   type-id:i32)
-    // 
-    llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
-    Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
-    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbrev);
-    llvm::SmallString<2048> Buffer;
-    {
-      llvm::raw_svector_ostream Out(Buffer);
-      for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
-           MEnd = Chain->ModuleMgr.end();
-           M != MEnd; ++M) {
-        StringRef FileName = (*M)->FileName;
-        io::Emit16(Out, FileName.size());
-        Out.write(FileName.data(), FileName.size());
-        io::Emit32(Out, (*M)->SLocEntryBaseOffset);
-        io::Emit32(Out, (*M)->BaseIdentifierID);
-        io::Emit32(Out, (*M)->BasePreprocessedEntityID);
-        io::Emit32(Out, (*M)->BaseSelectorID);
-        io::Emit32(Out, (*M)->BaseDeclID);
-        io::Emit32(Out, (*M)->BaseTypeIndex);
-      }
-    }
-    Record.clear();
-    Record.push_back(MODULE_OFFSET_MAP);
-    Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
-                              Buffer.data(), Buffer.size());
-  }
 
   // Create a lexical update block containing all of the declarations in the
   // translation unit that do not come from other AST files.
@@ -3030,6 +3027,51 @@
   }
   Stream.ExitBlock();
 
+  WriteFileDeclIDsMap();
+  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
+  
+  if (Chain) {
+    // Write the mapping information describing our module dependencies and how
+    // each of those modules were mapped into our own offset/ID space, so that
+    // the reader can build the appropriate mapping to its own offset/ID space.
+    // The map consists solely of a blob with the following format:
+    // *(module-name-len:i16 module-name:len*i8
+    //   source-location-offset:i32
+    //   identifier-id:i32
+    //   preprocessed-entity-id:i32
+    //   macro-definition-id:i32
+    //   selector-id:i32
+    //   declaration-id:i32
+    //   c++-base-specifiers-id:i32
+    //   type-id:i32)
+    // 
+    llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+    unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbrev);
+    llvm::SmallString<2048> Buffer;
+    {
+      llvm::raw_svector_ostream Out(Buffer);
+      for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
+           MEnd = Chain->ModuleMgr.end();
+           M != MEnd; ++M) {
+        StringRef FileName = (*M)->FileName;
+        io::Emit16(Out, FileName.size());
+        Out.write(FileName.data(), FileName.size());
+        io::Emit32(Out, (*M)->SLocEntryBaseOffset);
+        io::Emit32(Out, (*M)->BaseIdentifierID);
+        io::Emit32(Out, (*M)->BasePreprocessedEntityID);
+        io::Emit32(Out, (*M)->BaseSelectorID);
+        io::Emit32(Out, (*M)->BaseDeclID);
+        io::Emit32(Out, (*M)->BaseTypeIndex);
+      }
+    }
+    Record.clear();
+    Record.push_back(MODULE_OFFSET_MAP);
+    Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
+                              Buffer.data(), Buffer.size());
+  }
+
   WritePreprocessor(PP, IsModule);
   WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot);
   WriteSelectors(SemaRef);
@@ -3439,6 +3481,48 @@
   return DeclIDs[D];
 }
 
+static inline bool compLocDecl(std::pair<unsigned, serialization::DeclID> L,
+                               std::pair<unsigned, serialization::DeclID> R) {
+  return L.first < R.first;
+}
+
+void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID,
+                                      SourceLocation FileLoc) {
+  assert(ID);
+  assert(FileLoc.isValid());
+  assert(FileLoc.isFileID());
+
+  // We only keep track of the file-level declarations of each file.
+  if (!D->getLexicalDeclContext()->isFileContext())
+    return;
+
+  SourceManager &SM = Context->getSourceManager();
+  assert(SM.isLocalSourceLocation(FileLoc));
+  FileID FID = SM.getFileID(FileLoc);
+  if (FID.isInvalid())
+    return;
+  const SrcMgr::SLocEntry *Entry = &SM.getSLocEntry(FID);
+  assert(Entry->isFile());
+
+  DeclIDInFileInfo *&Info = FileDeclIDs[Entry];
+  if (!Info)
+    Info = new DeclIDInFileInfo();
+
+  unsigned RawLoc = FileLoc.getRawEncoding();
+  std::pair<unsigned, serialization::DeclID> LocDecl(RawLoc, ID);
+  LocDeclIDsTy &Decls = Info->DeclIDs;
+
+  if (Decls.empty() || Decls.back().first <= RawLoc) {
+    Decls.push_back(LocDecl);
+    return;
+  }
+
+  LocDeclIDsTy::iterator
+    I = std::upper_bound(Decls.begin(), Decls.end(), LocDecl, compLocDecl);
+
+  Decls.insert(I, LocDecl);
+}
+
 void ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) {
   // FIXME: Emit a stable enum for NameKind.  0 = Identifier etc.
   Record.push_back(Name.getNameKind());

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Oct 28 17:54:21 2011
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/DeclContextInternals.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1651,14 +1652,20 @@
     unsigned Index = ID - FirstDeclID;
 
     // Record the offset for this declaration
+    SourceLocation Loc = D->getLocation();
     if (DeclOffsets.size() == Index)
-      DeclOffsets.push_back(DeclOffset(D->getLocation(),
-                                       Stream.GetCurrentBitNo()));
+      DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
     else if (DeclOffsets.size() < Index) {
       DeclOffsets.resize(Index+1);
-      DeclOffsets[Index].setLocation(D->getLocation());
+      DeclOffsets[Index].setLocation(Loc);
       DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
     }
+    
+    SourceManager &SM = Context.getSourceManager();
+    if (Loc.isValid() && SM.isLocalSourceLocation(Loc)) {
+      SourceLocation FileLoc = SM.getFileLoc(Loc);
+      associateDeclWithFile(D, ID, FileLoc);
+    }
   }
 
   // Build and emit a record for this declaration

Modified: cfe/trunk/lib/Serialization/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/Module.cpp?rev=143238&r1=143237&r2=143238&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/Module.cpp (original)
+++ cfe/trunk/lib/Serialization/Module.cpp Fri Oct 28 17:54:21 2011
@@ -35,6 +35,7 @@
     SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
     DeclOffsets(0), BaseDeclID(0),
     LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
+    FileSortedDecls(0),
     LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0)
 {}
 





More information about the cfe-commits mailing list