njames93 updated this revision to Diff 400893.
njames93 added a comment.
Herald added a subscriber: carlosgalvezp.

Pre-allocate both vectors


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117529/new/

https://reviews.llvm.org/D117529

Files:
  clang-tools-extra/clang-tidy/ClangTidyModule.h
  clang-tools-extra/clangd/ParsedAST.cpp

Index: clang-tools-extra/clangd/ParsedAST.cpp
===================================================================
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -10,6 +10,7 @@
 #include "../clang-tidy/ClangTidyCheck.h"
 #include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
 #include "../clang-tidy/ClangTidyModuleRegistry.h"
+#include "../clang-tidy/GlobList.h"
 #include "AST.h"
 #include "Compiler.h"
 #include "Config.h"
@@ -45,6 +46,7 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -282,6 +284,59 @@
   }
 }
 
+// Turns a clang-tidy glob list into a BitVector that can be used to build the
+// necessary checks efficiently.
+class CachedFactories {
+  using FactoryFunc = std::function<std::unique_ptr<tidy::ClangTidyCheck>(
+      llvm::StringRef, tidy::ClangTidyContext *)>;
+  llvm::SmallVector<std::pair<std::string, FactoryFunc>, 0> AllChecks;
+  std::mutex Guard;
+  llvm::StringMap<llvm::BitVector> CachedGlobs;
+
+  llvm::BitVector &getCachedValue(StringRef CheckGlobString) {
+    std::lock_guard<std::mutex> LG(Guard);
+    auto It = CachedGlobs.find(CheckGlobString);
+    if (It != CachedGlobs.end())
+      return It->getValue();
+    // On the first time we see a glob, we construct the representation and
+    // cache it for the next time. In most projects there would only ever be one
+    // unique Glob.
+    tidy::GlobList Glob(CheckGlobString);
+    llvm::BitVector IsEnabled(AllChecks.size(), false);
+    for (size_t I = 0, E = AllChecks.size(); I != E; ++I) {
+      if (Glob.contains(AllChecks[I].first))
+        IsEnabled.set(I);
+    }
+    return CachedGlobs.insert_or_assign(CheckGlobString, std::move(IsEnabled))
+        .first->getValue();
+  }
+
+public:
+  CachedFactories() {
+    tidy::ClangTidyCheckFactories CTFactories;
+    for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
+      E.instantiate()->addCheckFactories(CTFactories);
+    AllChecks.reserve(CTFactories.size());
+    for (const auto &Item : CTFactories) {
+      AllChecks.emplace_back(Item.getKey(), Item.getValue());
+    }
+  }
+
+  std::vector<std::unique_ptr<tidy::ClangTidyCheck>>
+  createChecks(tidy::ClangTidyContext *Context) {
+    if (!Context->getOptions().Checks)
+      return {};
+    llvm::BitVector &IsEnabled = getCachedValue(*Context->getOptions().Checks);
+    std::vector<std::unique_ptr<tidy::ClangTidyCheck>> Result;
+    Result.reserve(IsEnabled.count());
+    for (unsigned CheckID : IsEnabled.set_bits()) {
+      Result.push_back(
+          AllChecks[CheckID].second(AllChecks[CheckID].first, Context));
+    }
+    return Result;
+  }
+};
+
 } // namespace
 
 llvm::Optional<ParsedAST>
@@ -410,15 +465,13 @@
   // diagnostics.
   if (PreserveDiags) {
     trace::Span Tracer("ClangTidyInit");
-    tidy::ClangTidyCheckFactories CTFactories;
-    for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
-      E.instantiate()->addCheckFactories(CTFactories);
+    static CachedFactories Factory;
     CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
         tidy::ClangTidyGlobalOptions(), ClangTidyOpts));
     CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
     CTContext->setASTContext(&Clang->getASTContext());
     CTContext->setCurrentFile(Filename);
-    CTChecks = CTFactories.createChecks(CTContext.getPointer());
+    CTChecks = Factory.createChecks(CTContext.getPointer());
     llvm::erase_if(CTChecks, [&](const auto &Check) {
       return !Check->isLanguageVersionSupported(CTContext->getLangOpts());
     });
Index: clang-tools-extra/clang-tidy/ClangTidyModule.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyModule.h
+++ clang-tools-extra/clang-tidy/ClangTidyModule.h
@@ -71,6 +71,7 @@
   FactoryMap::const_iterator begin() const { return Factories.begin(); }
   FactoryMap::const_iterator end() const { return Factories.end(); }
   bool empty() const { return Factories.empty(); }
+  size_t size() const { return Factories.size(); }
 
 private:
   FactoryMap Factories;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to