Skip to content

Commit c9adf31

Browse files
benlangmuirjansvoboda11
authored andcommitted
[clang][deps] Minor ModuleDepCollector refactorings NFC
* Factor module map and module file path functions out * Use a secondary mapping to lookup module deps by ID instead of the preprocessor module map. * Sink DirectPrebuiltModularDeps into MDC. Differential Revision: https://reviews.llvm.org/D132617
1 parent 4b5848d commit c9adf31

File tree

2 files changed

+73
-35
lines changed

2 files changed

+73
-35
lines changed

clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,6 @@ struct ModuleID {
6161
}
6262
};
6363

64-
struct ModuleIDHasher {
65-
std::size_t operator()(const ModuleID &MID) const {
66-
return llvm::hash_combine(MID.ModuleName, MID.ContextHash);
67-
}
68-
};
69-
7064
/// An output from a module compilation, such as the path of the module file.
7165
enum class ModuleOutputKind {
7266
/// The module file (.pcm). Required.
@@ -153,8 +147,6 @@ class ModuleDepCollectorPP final : public PPCallbacks {
153147
ModuleDepCollector &MDC;
154148
/// Working set of direct modular dependencies.
155149
llvm::SetVector<const Module *> DirectModularDeps;
156-
/// Working set of direct modular dependencies that have already been built.
157-
llvm::SetVector<const Module *> DirectPrebuiltModularDeps;
158150

159151
void handleImport(const Module *Imported);
160152

@@ -211,6 +203,11 @@ class ModuleDepCollector final : public DependencyCollector {
211203
std::vector<std::string> FileDeps;
212204
/// Direct and transitive modular dependencies of the main source file.
213205
llvm::MapVector<const Module *, std::unique_ptr<ModuleDeps>> ModularDeps;
206+
/// Secondary mapping for \c ModularDeps allowing lookup by ModuleID without
207+
/// a preprocessor. Storage owned by \c ModularDeps.
208+
llvm::DenseMap<ModuleID, ModuleDeps *> ModuleDepsByID;
209+
/// Direct modular dependencies that have already been built.
210+
llvm::MapVector<const Module *, PrebuiltModuleDep> DirectPrebuiltModularDeps;
214211
/// Options that control the dependency output generation.
215212
std::unique_ptr<DependencyOutputOptions> Opts;
216213
/// The original Clang invocation passed to dependency scanner.
@@ -235,12 +232,39 @@ class ModuleDepCollector final : public DependencyCollector {
235232
const ModuleDeps &Deps,
236233
llvm::function_ref<void(CompilerInvocation &)> Optimize) const;
237234

235+
/// Add module map files to the invocation, if needed.
236+
void addModuleMapFiles(CompilerInvocation &CI,
237+
ArrayRef<ModuleID> ClangModuleDeps) const;
238+
/// Add module files (pcm) to the invocation, if needed.
239+
void addModuleFiles(CompilerInvocation &CI,
240+
ArrayRef<ModuleID> ClangModuleDeps) const;
241+
238242
/// Add paths that require looking up outputs to the given dependencies.
239243
void addOutputPaths(CompilerInvocation &CI, ModuleDeps &Deps);
244+
245+
/// Compute the context hash for \p Deps, and create the mapping
246+
/// \c ModuleDepsByID[Deps.ID] = &Deps.
247+
void associateWithContextHash(const CompilerInvocation &CI, ModuleDeps &Deps);
240248
};
241249

242250
} // end namespace dependencies
243251
} // end namespace tooling
244252
} // end namespace clang
245253

254+
namespace llvm {
255+
template <> struct DenseMapInfo<clang::tooling::dependencies::ModuleID> {
256+
using ModuleID = clang::tooling::dependencies::ModuleID;
257+
static inline ModuleID getEmptyKey() { return ModuleID{"", ""}; }
258+
static inline ModuleID getTombstoneKey() {
259+
return ModuleID{"~", "~"}; // ~ is not a valid module name or context hash
260+
}
261+
static unsigned getHashValue(const ModuleID &ID) {
262+
return hash_combine(ID.ModuleName, ID.ContextHash);
263+
}
264+
static bool isEqual(const ModuleID &LHS, const ModuleID &RHS) {
265+
return LHS == RHS;
266+
}
267+
};
268+
} // namespace llvm
269+
246270
#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,7 @@ void ModuleDepCollector::addOutputPaths(CompilerInvocation &CI,
5757
// These are technically *inputs* to the compilation, but we populate them
5858
// here in order to make \c getModuleContextHash() independent of
5959
// \c lookupModuleOutput().
60-
for (ModuleID MID : Deps.ClangModuleDeps) {
61-
auto PCMPath =
62-
Consumer.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
63-
if (EagerLoadModules)
64-
CI.getFrontendOpts().ModuleFiles.push_back(PCMPath);
65-
else
66-
CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert(
67-
{MID.ModuleName, PCMPath});
68-
}
60+
addModuleFiles(CI, Deps.ClangModuleDeps);
6961

7062
CI.getFrontendOpts().OutputFile =
7163
Consumer.lookupModuleOutput(Deps.ID, ModuleOutputKind::ModuleFile);
@@ -127,24 +119,12 @@ ModuleDepCollector::makeInvocationForModuleBuildWithoutOutputs(
127119
CI.getFrontendOpts().Inputs.emplace_back(Deps.ClangModuleMapFile,
128120
ModuleMapInputKind);
129121
CI.getFrontendOpts().ModuleMapFiles = Deps.ModuleMapFileDeps;
122+
addModuleMapFiles(CI, Deps.ClangModuleDeps);
130123

131124
// Report the prebuilt modules this module uses.
132125
for (const auto &PrebuiltModule : Deps.PrebuiltModuleDeps)
133126
CI.getFrontendOpts().ModuleFiles.push_back(PrebuiltModule.PCMFile);
134127

135-
if (!EagerLoadModules) {
136-
ModuleMap &ModMap =
137-
ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
138-
for (ModuleID MID : Deps.ClangModuleDeps) {
139-
const Module *M = ModMap.findModule(MID.ModuleName);
140-
assert(M && "Modular dependency not found");
141-
auto MDeps = ModularDeps.find(M);
142-
assert(MDeps != ModularDeps.end() && "Inconsistent dependency info");
143-
CI.getFrontendOpts().ModuleMapFiles.push_back(
144-
MDeps->second->ClangModuleMapFile);
145-
}
146-
}
147-
148128
// Remove any macro definitions that are explicitly ignored.
149129
if (!CI.getHeaderSearchOpts().ModulesIgnoreMacros.empty()) {
150130
llvm::erase_if(
@@ -171,6 +151,31 @@ ModuleDepCollector::makeInvocationForModuleBuildWithoutOutputs(
171151
return CI;
172152
}
173153

154+
void ModuleDepCollector::addModuleMapFiles(
155+
CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
156+
if (EagerLoadModules)
157+
return; // Only pcm is needed for eager load.
158+
159+
for (const ModuleID &MID : ClangModuleDeps) {
160+
ModuleDeps *MD = ModuleDepsByID.lookup(MID);
161+
assert(MD && "Inconsistent dependency info");
162+
CI.getFrontendOpts().ModuleMapFiles.push_back(MD->ClangModuleMapFile);
163+
}
164+
}
165+
166+
void ModuleDepCollector::addModuleFiles(
167+
CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
168+
for (const ModuleID &MID : ClangModuleDeps) {
169+
std::string PCMPath =
170+
Consumer.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
171+
if (EagerLoadModules)
172+
CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
173+
else
174+
CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert(
175+
{MID.ModuleName, std::move(PCMPath)});
176+
}
177+
}
178+
174179
static std::string getModuleContextHash(const ModuleDeps &MD,
175180
const CompilerInvocation &CI,
176181
bool EagerLoadModules) {
@@ -212,6 +217,14 @@ static std::string getModuleContextHash(const ModuleDeps &MD,
212217
return toString(llvm::APInt(sizeof(Words) * 8, Words), 36, /*Signed=*/false);
213218
}
214219

220+
void ModuleDepCollector::associateWithContextHash(const CompilerInvocation &CI,
221+
ModuleDeps &Deps) {
222+
Deps.ID.ContextHash = getModuleContextHash(Deps, CI, EagerLoadModules);
223+
bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second;
224+
(void)Inserted;
225+
assert(Inserted && "duplicate module mapping");
226+
}
227+
215228
void ModuleDepCollectorPP::FileChanged(SourceLocation Loc,
216229
FileChangeReason Reason,
217230
SrcMgr::CharacteristicKind FileType,
@@ -263,7 +276,8 @@ void ModuleDepCollectorPP::handleImport(const Module *Imported) {
263276
const Module *TopLevelModule = Imported->getTopLevelModule();
264277

265278
if (MDC.isPrebuiltModule(TopLevelModule))
266-
DirectPrebuiltModularDeps.insert(TopLevelModule);
279+
MDC.DirectPrebuiltModularDeps.insert(
280+
{TopLevelModule, PrebuiltModuleDep{TopLevelModule}});
267281
else
268282
DirectModularDeps.insert(TopLevelModule);
269283
}
@@ -300,8 +314,8 @@ void ModuleDepCollectorPP::EndOfMainFile() {
300314
for (auto &&I : MDC.FileDeps)
301315
MDC.Consumer.handleFileDependency(I);
302316

303-
for (auto &&I : DirectPrebuiltModularDeps)
304-
MDC.Consumer.handlePrebuiltModuleDependency(PrebuiltModuleDep{I});
317+
for (auto &&I : MDC.DirectPrebuiltModularDeps)
318+
MDC.Consumer.handlePrebuiltModuleDependency(I.second);
305319
}
306320

307321
ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
@@ -403,8 +417,8 @@ ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
403417
*MDC.ScanInstance.getASTReader(), *MF);
404418
});
405419

406-
// Compute the context hash from the inputs. Requires dependencies.
407-
MD.ID.ContextHash = getModuleContextHash(MD, CI, MDC.EagerLoadModules);
420+
MDC.associateWithContextHash(CI, MD);
421+
408422
// Finish the compiler invocation. Requires dependencies and the context hash.
409423
MDC.addOutputPaths(CI, MD);
410424

0 commit comments

Comments
 (0)