https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/65691:
>From 6b8c1ee1507fbc143752fac966e4aabb36699e53 Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Fri, 1 Sep 2023 13:01:24 -0700 Subject: [PATCH] [clang][deps] Generate command-lines lazily --- .../DependencyScanning/ModuleDepCollector.h | 13 ++++++--- .../DependencyScanning/ModuleDepCollector.cpp | 10 ++++++- clang/tools/clang-scan-deps/ClangScanDeps.cpp | 27 ++++++++++++------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index ef75c580552181c..f5dbb26452da4e6 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -23,6 +23,7 @@ #include <optional> #include <string> #include <unordered_map> +#include <variant> namespace clang { namespace tooling { @@ -136,9 +137,15 @@ struct ModuleDeps { /// determined that the differences are benign for this compilation. std::vector<ModuleID> ClangModuleDeps; - /// Compiler invocation that can be used to build this module. Does not - /// include argv[0]. - std::vector<std::string> BuildArguments; + /// Get (or compute) the compiler invocation that can be used to build this + /// module. Does not include argv[0]. + const std::vector<std::string> &getBuildArguments(); + +private: + friend class ModuleDepCollectorPP; + + std::variant<std::monostate, CowCompilerInvocation, std::vector<std::string>> + BuildInfo; }; class ModuleDepCollector; diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index a7248860ad4b567..7e03a415377921f 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -21,6 +21,14 @@ using namespace clang; using namespace tooling; using namespace dependencies; +const std::vector<std::string> &ModuleDeps::getBuildArguments() { + assert(!std::holds_alternative<std::monostate>(BuildInfo) && + "Using uninitialized ModuleDeps"); + if (const auto *CI = std::get_if<CowCompilerInvocation>(&BuildInfo)) + BuildInfo = CI->getCC1CommandLine(); + return std::get<std::vector<std::string>>(BuildInfo); +} + static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader, const serialization::ModuleFile &MF) { @@ -532,7 +540,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { // Finish the compiler invocation. Requires dependencies and the context hash. MDC.addOutputPaths(CI, MD); - MD.BuildArguments = CI.getCC1CommandLine(); + MD.BuildInfo = std::move(CI); return MD.ID; } diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index dab3de42b7fa1af..0213bb9c9616d67 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -351,14 +351,23 @@ class FullDeps { } void mergeDeps(ModuleDepsGraph Graph, size_t InputIndex) { - std::unique_lock<std::mutex> ul(Lock); - for (const ModuleDeps &MD : Graph) { - auto I = Modules.find({MD.ID, 0}); - if (I != Modules.end()) { - I->first.InputIndex = std::min(I->first.InputIndex, InputIndex); - continue; + std::vector<ModuleDeps *> NewMDs; + { + std::unique_lock<std::mutex> ul(Lock); + for (const ModuleDeps &MD : Graph) { + auto I = Modules.find({MD.ID, 0}); + if (I != Modules.end()) { + I->first.InputIndex = std::min(I->first.InputIndex, InputIndex); + continue; + } + auto Res = Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)}); + NewMDs.push_back(&Res->second); } - Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)}); + // First call to \c getBuildArguments is somewhat expensive. Let's call it + // on the current thread (instead of the main one), and outside the + // critical section. + for (ModuleDeps *MD : NewMDs) + (void)MD->getBuildArguments(); } } @@ -382,7 +391,7 @@ class FullDeps { /*ShouldOwnClient=*/false); for (auto &&M : Modules) - if (roundTripCommand(M.second.BuildArguments, *Diags)) + if (roundTripCommand(M.second.getBuildArguments(), *Diags)) return true; for (auto &&I : Inputs) @@ -411,7 +420,7 @@ class FullDeps { {"file-deps", toJSONSorted(MD.FileDeps)}, {"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)}, {"clang-modulemap-file", MD.ClangModuleMapFile}, - {"command-line", MD.BuildArguments}, + {"command-line", MD.getBuildArguments()}, }; OutModules.push_back(std::move(O)); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits