Cache visible Clang modules for interface printing in 'ModuleDecl'

Instead of caching the collection of visible Clang modules in the 'TypePrinter', compute and cache them in the 'ModuleDecl'. When printing a textual interface, the compiler will instantiate many new instances of 'TypePrinter', which means caching them there is not useful.
This commit is contained in:
Artem Chikin
2024-06-11 13:01:52 -07:00
parent 5dbf31a5d3
commit 71ec06e656
3 changed files with 63 additions and 56 deletions

View File

@@ -1719,6 +1719,54 @@ void ModuleDecl::getMissingImportedModules(
FORWARD(getMissingImportedModules, (imports));
}
const llvm::DenseMap<const clang::Module *, ModuleDecl *> &
ModuleDecl::getVisibleClangModules(PrintOptions::InterfaceMode contentMode) {
if (CachedVisibleClangModuleSet.find(contentMode) != CachedVisibleClangModuleSet.end())
return CachedVisibleClangModuleSet[contentMode];
else
CachedVisibleClangModuleSet.emplace(contentMode, VisibleClangModuleSet{});
VisibleClangModuleSet &result = CachedVisibleClangModuleSet[contentMode];
// For the current module, consider both private and public imports.
ModuleDecl::ImportFilter Filter = ModuleDecl::ImportFilterKind::Exported;
Filter |= ModuleDecl::ImportFilterKind::Default;
// For private or package swiftinterfaces, also look through @_spiOnly imports.
if (contentMode != PrintOptions::InterfaceMode::Public)
Filter |= ModuleDecl::ImportFilterKind::SPIOnly;
// Consider package import for package interface
if (contentMode == PrintOptions::InterfaceMode::Package)
Filter |= ModuleDecl::ImportFilterKind::PackageOnly;
SmallVector<ImportedModule, 32> Imports;
getImportedModules(Imports, Filter);
SmallVector<ModuleDecl *, 32> ModulesToProcess;
for (const auto &Import : Imports)
ModulesToProcess.push_back(Import.importedModule);
SmallPtrSet<ModuleDecl *, 32> Processed;
while (!ModulesToProcess.empty()) {
ModuleDecl *Mod = ModulesToProcess.back();
ModulesToProcess.pop_back();
if (!Processed.insert(Mod).second)
continue;
if (const clang::Module *ClangModule = Mod->findUnderlyingClangModule())
result[ClangModule] = Mod;
// For transitive imports, consider only public imports.
Imports.clear();
Mod->getImportedModules(Imports, ModuleDecl::ImportFilterKind::Exported);
for (const auto &Import : Imports) {
ModulesToProcess.push_back(Import.importedModule);
}
}
return result;
}
void
SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
ModuleDecl::ImportFilter filter) const {