[clang] 3b1a686 - [clang][deps] Generate command lines lazily (#65691)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 7 17:45:57 PDT 2023
Author: Jan Svoboda
Date: 2023-09-07T17:45:53-07:00
New Revision: 3b1a68655e1760680b4786afb56dbb5acde272a0
URL: https://github.com/llvm/llvm-project/commit/3b1a68655e1760680b4786afb56dbb5acde272a0
DIFF: https://github.com/llvm/llvm-project/commit/3b1a68655e1760680b4786afb56dbb5acde272a0.diff
LOG: [clang][deps] Generate command lines lazily (#65691)
This patch makes the generation of command lines for modular
dependencies lazy/on-demand. That operation is somewhat expensive and
prior to this patch used to be performed multiple times for the
identical `ModuleDeps` (i.e. when they were imported from multiple
different TUs).
Added:
Modified:
clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
clang/tools/clang-scan-deps/ClangScanDeps.cpp
Removed:
################################################################################
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
diff erences 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));
}
More information about the cfe-commits
mailing list