gamesh411 created this revision.
gamesh411 added a reviewer: martong.
Herald added subscribers: cfe-commits, Szelethus, dkrupp, rnkovacs.
Herald added a project: clang.

Refactor loadExternalAST method of CrossTranslationUnitContext in order to
reduce maintenance burden and so that features are easier to add in the future.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64753

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp

Index: clang/lib/CrossTU/CrossTranslationUnit.cpp
===================================================================
--- clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -237,8 +237,8 @@
   if (LookupName.empty())
     return llvm::make_error<IndexError>(
         index_error_code::failed_to_generate_usr);
-  llvm::Expected<ASTUnit *> ASTUnitOrError = loadExternalAST(
-      LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
+  llvm::Expected<ASTUnit *> ASTUnitOrError =
+      loadExternalAST(LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
   if (!ASTUnitOrError)
     return ASTUnitOrError.takeError();
   ASTUnit *Unit = *ASTUnitOrError;
@@ -340,6 +340,92 @@
   }
 }
 
+bool CrossTranslationUnitContext::checkThresholdReached() const {
+  if (NumASTLoaded >= CTULoadThreshold) {
+    ++NumASTLoadThresholdReached;
+    return true;
+  }
+  return false;
+}
+
+llvm::Error CrossTranslationUnitContext::lazyInitCTUIndex(StringRef CrossTUDir,
+                                                          StringRef IndexName) {
+  // Dont initialize if the map is filled.
+  if (!NameFileMap.empty())
+    return llvm::Error::success();
+
+  // Get the absolute path to the index file.
+  SmallString<256> IndexFile = CrossTUDir;
+  if (llvm::sys::path::is_absolute(IndexName))
+    IndexFile = IndexName;
+  else
+    llvm::sys::path::append(IndexFile, IndexName);
+
+  if (auto IndexMapping = parseCrossTUIndex(IndexFile, CrossTUDir)) {
+    // Initialize member map.
+    NameFileMap = *IndexMapping;
+    return llvm::Error::success();
+  } else {
+    // Error while parsing CrossTU index file.
+    return IndexMapping.takeError();
+  };
+}
+
+ASTUnit *CrossTranslationUnitContext::getCachedASTUnitForName(
+    StringRef LookupName) const {
+  auto CacheEntry = NameASTUnitMap.find(LookupName);
+  if (CacheEntry != NameASTUnitMap.end())
+    return CacheEntry->second;
+  else
+    return nullptr;
+}
+
+std::unique_ptr<ASTUnit>
+CrossTranslationUnitContext::loadFromASTFile(StringRef ASTFileName) const {
+  // Load AST from ast-dump.
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  TextDiagnosticPrinter *DiagClient =
+      new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
+
+  return ASTUnit::LoadFromASTFile(
+      ASTFileName, CI.getPCHContainerOperations()->getRawReader(),
+      ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts());
+}
+
+llvm::Expected<std::string>
+CrossTranslationUnitContext::getASTFileNameForLookup(
+    StringRef LookupName) const {
+  auto NameFileMapEntry = NameFileMap.find(LookupName);
+  if (NameFileMapEntry != NameFileMap.end()) {
+    return NameFileMapEntry->second;
+  } else {
+    ++NumNotInOtherTU;
+    return llvm::make_error<IndexError>(index_error_code::missing_definition);
+  }
+}
+
+ASTUnit *
+CrossTranslationUnitContext::loadFromASTFileCached(StringRef LookupName,
+                                                   StringRef ASTFileName) {
+  ASTUnit *Unit = nullptr;
+
+  auto ASTCacheEntry = FileASTUnitMap.find(ASTFileName);
+  if (ASTCacheEntry == FileASTUnitMap.end()) {
+    // Load the ASTUnit from the pre-dumped AST file specified by ASTFileName.
+    std::unique_ptr<ASTUnit> LoadedUnit = loadFromASTFile(ASTFileName);
+    Unit = LoadedUnit.get();
+    FileASTUnitMap[ASTFileName] = std::move(LoadedUnit);
+  } else {
+    Unit = ASTCacheEntry->second.get();
+  }
+  NameASTUnitMap[LookupName] = Unit;
+
+  return Unit;
+}
+
 llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
     StringRef LookupName, StringRef CrossTUDir, StringRef IndexName,
     bool DisplayCTUProgress) {
@@ -348,65 +434,38 @@
   //        translation units contains decls with the same lookup name an
   //        error will be returned.
 
-  if (NumASTLoaded >= CTULoadThreshold) {
-    ++NumASTLoadThresholdReached;
+  // If import threshold is reached, don't import anything.
+  if (checkThresholdReached())
     return llvm::make_error<IndexError>(
         index_error_code::load_threshold_reached);
-  }
 
-  ASTUnit *Unit = nullptr;
-  auto NameUnitCacheEntry = NameASTUnitMap.find(LookupName);
-  if (NameUnitCacheEntry == NameASTUnitMap.end()) {
-    if (NameFileMap.empty()) {
-      SmallString<256> IndexFile = CrossTUDir;
-      if (llvm::sys::path::is_absolute(IndexName))
-        IndexFile = IndexName;
-      else
-        llvm::sys::path::append(IndexFile, IndexName);
-      llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
-          parseCrossTUIndex(IndexFile, CrossTUDir);
-      if (IndexOrErr)
-        NameFileMap = *IndexOrErr;
-      else
-        return IndexOrErr.takeError();
-    }
+  // First try to access the cache to get the ASTUnit for the function name
+  // specified by LookupName.
+  ASTUnit *Unit = getCachedASTUnitForName(LookupName);
+  if (Unit)
+    return Unit;
 
-    auto It = NameFileMap.find(LookupName);
-    if (It == NameFileMap.end()) {
-      ++NumNotInOtherTU;
-      return llvm::make_error<IndexError>(index_error_code::missing_definition);
-    }
-    StringRef ASTFileName = It->second;
-    auto ASTCacheEntry = FileASTUnitMap.find(ASTFileName);
-    if (ASTCacheEntry == FileASTUnitMap.end()) {
-      IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-      TextDiagnosticPrinter *DiagClient =
-          new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
-      IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-      IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-          new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
-
-      std::unique_ptr<ASTUnit> LoadedUnit(ASTUnit::LoadFromASTFile(
-          ASTFileName, CI.getPCHContainerOperations()->getRawReader(),
-          ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts()));
-      Unit = LoadedUnit.get();
-      FileASTUnitMap[ASTFileName] = std::move(LoadedUnit);
-      ++NumASTLoaded;
-      if (DisplayCTUProgress) {
-        llvm::errs() << "CTU loaded AST file: "
-                     << ASTFileName << "\n";
-      }
-    } else {
-      Unit = ASTCacheEntry->second.get();
+  // Lazily initialize the mapping from function names to AST files.
+  if (llvm::Error InitFailed = lazyInitCTUIndex(CrossTUDir, IndexName))
+    return std::move(InitFailed);
+
+  llvm::Expected<std::string> ASTFileName = getASTFileNameForLookup(LookupName);
+  if (!ASTFileName)
+    return ASTFileName.takeError();
+
+  // Try to load from ASTFile but use cache for both file and function names.
+  Unit = loadFromASTFileCached(LookupName, *ASTFileName);
+
+  if (Unit) {
+    ++NumASTLoaded;
+    if (DisplayCTUProgress) {
+      llvm::errs() << "CTU loaded AST file: " << *ASTFileName << "\n";
     }
-    NameASTUnitMap[LookupName] = Unit;
+    return Unit;
   } else {
-    Unit = NameUnitCacheEntry->second;
-  }
-  if (!Unit)
     return llvm::make_error<IndexError>(
         index_error_code::failed_to_get_external_ast);
-  return Unit;
+  }
 }
 
 template <typename T>
Index: clang/include/clang/CrossTU/CrossTranslationUnit.h
===================================================================
--- clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -163,16 +163,22 @@
   void emitCrossTUDiagnostics(const IndexError &IE);
 
 private:
+  bool checkThresholdReached() const;
+  llvm::Error lazyInitCTUIndex(StringRef CrossTUDir, StringRef IndexName);
+  ASTUnit *getCachedASTUnitForName(StringRef LookupName) const;
+  std::unique_ptr<ASTUnit> loadFromASTFile(StringRef ASTFileName) const;
+  ASTUnit *loadFromASTFileCached(StringRef LookupName, StringRef ASTFileName);
+  llvm::Expected<std::string>
+  getASTFileNameForLookup(StringRef LookupName) const;
+
   void lazyInitImporterSharedSt(TranslationUnitDecl *ToTU);
   ASTImporter &getOrCreateASTImporter(ASTContext &From);
   template <typename T>
-  llvm::Expected<const T *> getCrossTUDefinitionImpl(const T *D,
-                                                     StringRef CrossTUDir,
-                                                     StringRef IndexName,
-                                                     bool DisplayCTUProgress);
+  llvm::Expected<const T *>
+  getCrossTUDefinitionImpl(const T *D, StringRef CrossTUDir,
+                           StringRef IndexName, bool DisplayCTUProgress);
   template <typename T>
-  const T *findDefInDeclContext(const DeclContext *DC,
-                                StringRef LookupName);
+  const T *findDefInDeclContext(const DeclContext *DC, StringRef LookupName);
   template <typename T>
   llvm::Expected<const T *> importDefinitionImpl(const T *D);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to