r244285 - [modules] Stop walking all modules when looking for lexical decls for a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 6 15:07:25 PDT 2015


Author: rsmith
Date: Thu Aug  6 17:07:25 2015
New Revision: 244285

URL: http://llvm.org/viewvc/llvm-project?rev=244285&view=rev
Log:
[modules] Stop walking all modules when looking for lexical decls for a
DeclContext. These only ever come from the owning module file for the Decl.

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

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=244285&r1=244284&r2=244285&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Aug  6 17:07:25 2015
@@ -61,9 +61,6 @@ namespace clang {
     /// used for the translation unit declaration.
     typedef uint32_t DeclID;
 
-    /// \brief a Decl::Kind/DeclID pair.
-    typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
-
     // FIXME: Turn these into classes so we can have some type safety when
     // we go from local ID to global and vice-versa.
     typedef DeclID LocalDeclID;

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=244285&r1=244284&r2=244285&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Aug  6 17:07:25 2015
@@ -494,6 +494,16 @@ private:
   /// \brief Map from a FileID to the file-level declarations that it contains.
   llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs;
 
+  /// \brief An array of lexical contents of a declaration context, as a sequence of
+  /// Decl::Kind, DeclID pairs.
+  typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
+
+  /// \brief Map from a DeclContext to its lexical contents.
+  llvm::DenseMap<const DeclContext*, LexicalContents> LexicalDecls;
+
+  /// \brief Map from the TU to its lexical contents from each module file.
+  std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
+
   // Updates for visible decls can occur for other contexts than just the
   // TU, and when we read those update records, the actual context may not
   // be available yet, so have this pending map using the ID as a key. It

Modified: cfe/trunk/include/clang/Serialization/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=244285&r1=244284&r2=244285&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/Module.h (original)
+++ cfe/trunk/include/clang/Serialization/Module.h Thu Aug  6 17:07:25 2015
@@ -52,12 +52,10 @@ enum ModuleKind {
 
 /// \brief Information about the contents of a DeclContext.
 struct DeclContextInfo {
-  DeclContextInfo()
-    : NameLookupTableData(), LexicalDecls() {}
+  DeclContextInfo() : NameLookupTableData() {}
 
   llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
     *NameLookupTableData; // an ASTDeclContextNameLookupTable.
-  ArrayRef<KindDeclIDPair> LexicalDecls;
 };
 
 /// \brief The input file that has been loaded from this AST file, along with

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=244285&r1=244284&r2=244285&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Aug  6 17:07:25 2015
@@ -973,9 +973,13 @@ bool ASTReader::ReadLexicalDeclContextSt
     return true;
   }
 
-  M.DeclContextInfos[DC].LexicalDecls = llvm::makeArrayRef(
-      reinterpret_cast<const KindDeclIDPair *>(Blob.data()),
-      Blob.size() / sizeof(KindDeclIDPair));
+  assert(!isa<TranslationUnitDecl>(DC) &&
+         "expected a TU_UPDATE_LEXICAL record for TU");
+  // FIXME: Once we remove RewriteDecl, assert that we didn't already have
+  // lexical decls for this context.
+  LexicalDecls[DC] = llvm::makeArrayRef(
+      reinterpret_cast<const llvm::support::unaligned_uint32_t *>(Blob.data()),
+      Blob.size() / 4);
   DC->setHasExternalLexicalStorage(true);
   return false;
 }
@@ -2498,10 +2502,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
         
     case TU_UPDATE_LEXICAL: {
       DeclContext *TU = Context.getTranslationUnitDecl();
-      DeclContextInfo &Info = F.DeclContextInfos[TU];
-      Info.LexicalDecls = llvm::makeArrayRef(
-          reinterpret_cast<const KindDeclIDPair *>(Blob.data()),
-          static_cast<unsigned int>(Blob.size() / sizeof(KindDeclIDPair)));
+      LexicalContents Contents(
+          reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
+              Blob.data()),
+          static_cast<unsigned int>(Blob.size() / 4));
+      TULexicalDecls.push_back(std::make_pair(&F, Contents));
       TU->setHasExternalLexicalStorage(true);
       break;
     }
@@ -6175,69 +6180,45 @@ Stmt *ASTReader::GetExternalDeclStmt(uin
   return ReadStmtFromStream(*Loc.F);
 }
 
-namespace {
-  class FindExternalLexicalDeclsVisitor {
-    ASTReader &Reader;
-    const DeclContext *DC;
-    llvm::function_ref<bool(Decl::Kind)> IsKindWeWant;
-    
-    SmallVectorImpl<Decl*> &Decls;
-    bool PredefsVisited[NUM_PREDEF_DECL_IDS];
-
-  public:
-    FindExternalLexicalDeclsVisitor(
-        ASTReader &Reader, const DeclContext *DC,
-        llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
-        SmallVectorImpl<Decl *> &Decls)
-        : Reader(Reader), DC(DC), IsKindWeWant(IsKindWeWant), Decls(Decls) {
-      for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)
-        PredefsVisited[I] = false;
-    }
+void ASTReader::FindExternalLexicalDecls(
+    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
+    SmallVectorImpl<Decl *> &Decls) {
+  bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};
 
-    static bool visitPostorder(ModuleFile &M, void *UserData) {
-      return (*static_cast<FindExternalLexicalDeclsVisitor*>(UserData))(M);
-    }
+  auto Visit = [&] (ModuleFile *M, const LexicalContents &LexicalDecls) {
+    assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
+    for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
+      auto K = (Decl::Kind)+LexicalDecls[I];
+      if (!IsKindWeWant(K))
+        continue;
 
-    bool operator()(ModuleFile &M) {
-      ModuleFile::DeclContextInfosMap::iterator Info =
-          M.DeclContextInfos.find(DC);
-      if (Info == M.DeclContextInfos.end() || Info->second.LexicalDecls.empty())
-        return false;
+      auto ID = (serialization::DeclID)+LexicalDecls[I + 1];
 
-      // Load all of the declaration IDs
-      for (const KindDeclIDPair &P : Info->second.LexicalDecls) {
-        if (!IsKindWeWant((Decl::Kind)P.first))
+      // Don't add predefined declarations to the lexical context more
+      // than once.
+      if (ID < NUM_PREDEF_DECL_IDS) {
+        if (PredefsVisited[ID])
           continue;
 
-        // Don't add predefined declarations to the lexical context more
-        // than once.
-        if (P.second < NUM_PREDEF_DECL_IDS) {
-          if (PredefsVisited[P.second])
-            continue;
-
-          PredefsVisited[P.second] = true;
-        }
-
-        if (Decl *D = Reader.GetLocalDecl(M, P.second)) {
-          if (!DC->isDeclInLexicalTraversal(D))
-            Decls.push_back(D);
-        }
+        PredefsVisited[ID] = true;
       }
 
-      return false;
+      if (Decl *D = GetLocalDecl(*M, ID)) {
+        if (!DC->isDeclInLexicalTraversal(D))
+          Decls.push_back(D);
+      }
     }
   };
-}
 
-void ASTReader::FindExternalLexicalDecls(
-    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
-    SmallVectorImpl<Decl *> &Decls) {
-  // There might be lexical decls in multiple modules, for the TU at
-  // least. FIXME: Only look in multiple module files in the very rare
-  // cases where this can actually happen.
-  FindExternalLexicalDeclsVisitor Visitor(*this, DC, IsKindWeWant, Decls);
-  ModuleMgr.visitDepthFirst(
-      nullptr, &FindExternalLexicalDeclsVisitor::visitPostorder, &Visitor);
+  if (isa<TranslationUnitDecl>(DC)) {
+    for (auto Lexical : TULexicalDecls)
+      Visit(Lexical.first, Lexical.second);
+  } else {
+    auto I = LexicalDecls.find(DC);
+    if (I != LexicalDecls.end())
+      Visit(getOwningModuleFile(cast<Decl>(DC)), I->second);
+  }
+
   ++NumLexicalDeclContextsRead;
 }
 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=244285&r1=244284&r2=244285&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Aug  6 17:07:25 2015
@@ -2738,12 +2738,15 @@ uint64_t ASTWriter::WriteDeclContextLexi
   uint64_t Offset = Stream.GetCurrentBitNo();
   RecordData Record;
   Record.push_back(DECL_CONTEXT_LEXICAL);
-  SmallVector<KindDeclIDPair, 64> Decls;
-  for (const auto *D : DC->decls())
-    Decls.push_back(std::make_pair(D->getKind(), GetDeclRef(D)));
+  SmallVector<uint32_t, 128> KindDeclPairs;
+  for (const auto *D : DC->decls()) {
+    KindDeclPairs.push_back(D->getKind());
+    KindDeclPairs.push_back(GetDeclRef(D));
+  }
 
   ++NumLexicalDeclContexts;
-  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, bytes(Decls));
+  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record,
+                            bytes(KindDeclPairs));
   return Offset;
 }
 
@@ -4288,10 +4291,12 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   // Create a lexical update block containing all of the declarations in the
   // translation unit that do not come from other AST files.
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
-  SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
-  for (const auto *I : TU->noload_decls()) {
-    if (!I->isFromASTFile())
-      NewGlobalDecls.push_back(std::make_pair(I->getKind(), GetDeclRef(I)));
+  SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
+  for (const auto *D : TU->noload_decls()) {
+    if (!D->isFromASTFile()) {
+      NewGlobalKindDeclPairs.push_back(D->getKind());
+      NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
+    }
   }
   
   llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
@@ -4301,7 +4306,7 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   Record.clear();
   Record.push_back(TU_UPDATE_LEXICAL);
   Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
-                            bytes(NewGlobalDecls));
+                            bytes(NewGlobalKindDeclPairs));
   
   // And a visible updates block for the translation unit.
   Abv = new llvm::BitCodeAbbrev();




More information about the cfe-commits mailing list