Skip to content

[clang][deps] Generate command lines lazily #65691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <optional>
#include <string>
#include <unordered_map>
#include <variant>

namespace clang {
namespace tooling {
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
27 changes: 18 additions & 9 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

Expand All @@ -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)
Expand Down Expand Up @@ -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));
}
Expand Down