[Dependency Scanning] Move generation of a named import path 'Identifier' out of the individual scanning workers up into the parent scanner. This operation mutates the scanner ASTContext by potentially adding new identifiers to it and is therefore not thread-safe.

This commit is contained in:
Artem Chikin
2023-12-05 10:10:54 -08:00
parent ff63a900aa
commit 674dfb3bd4
10 changed files with 48 additions and 35 deletions

View File

@@ -341,7 +341,7 @@ public:
/// Retrieve the dependencies for the given, named module, or \c None /// Retrieve the dependencies for the given, named module, or \c None
/// if no such module exists. /// if no such module exists.
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,

View File

@@ -440,7 +440,7 @@ public:
StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr); StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr);
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath, getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool, clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,

View File

@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "swift/AST/ASTContext.h" #include "swift/AST/ASTContext.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/ModuleDependencies.h" #include "swift/AST/ModuleDependencies.h"
#include "swift/Frontend/ModuleInterfaceLoader.h" #include "swift/Frontend/ModuleInterfaceLoader.h"
#include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/SerializedModuleLoader.h"
@@ -36,18 +37,18 @@ public:
private: private:
/// Retrieve the module dependencies for the module with the given name. /// Retrieve the module dependencies for the module with the given name.
ModuleDependencyVector ModuleDependencyVector
scanFilesystemForModuleDependency(StringRef moduleName, scanFilesystemForModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache, const ModuleDependenciesCache &cache,
bool isTestableImport = false); bool isTestableImport = false);
/// Retrieve the module dependencies for the Clang module with the given name. /// Retrieve the module dependencies for the Clang module with the given name.
ModuleDependencyVector ModuleDependencyVector
scanFilesystemForClangModuleDependency(StringRef moduleName, scanFilesystemForClangModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache); const ModuleDependenciesCache &cache);
/// Retrieve the module dependencies for the Swift module with the given name. /// Retrieve the module dependencies for the Swift module with the given name.
ModuleDependencyVector ModuleDependencyVector
scanFilesystemForSwiftModuleDependency(StringRef moduleName, scanFilesystemForSwiftModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache); const ModuleDependenciesCache &cache);
// An AST delegate for interface scanning. // An AST delegate for interface scanning.
@@ -135,6 +136,8 @@ private:
template <typename Function, typename... Args> template <typename Function, typename... Args>
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList); auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);
Identifier getModuleImportIdentifier(StringRef moduleName);
private: private:
const CompilerInvocation &ScanCompilerInvocation; const CompilerInvocation &ScanCompilerInvocation;
ASTContext &ScanASTContext; ASTContext &ScanASTContext;

View File

@@ -98,7 +98,7 @@ public:
} }
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath, getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool, clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,

View File

@@ -250,7 +250,7 @@ public:
virtual void verifyAllModules() override; virtual void verifyAllModules() override;
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath, getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool, clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,

View File

@@ -101,10 +101,12 @@ ModuleSearchPathLookup::searchPathsContainingFile(
llvm::SmallSet<std::pair<ModuleSearchPathKind, unsigned>, 4> ResultIds; llvm::SmallSet<std::pair<ModuleSearchPathKind, unsigned>, 4> ResultIds;
for (auto &Filename : Filenames) { for (auto &Filename : Filenames) {
for (auto &Entry : LookupTable.lookup(Filename)) { if (LookupTable.contains(Filename)) {
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex())) for (auto &Entry : LookupTable.at(Filename)) {
.second) { if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
Result.push_back(Entry.get()); .second) {
Result.push_back(Entry.get());
}
} }
} }
} }

View File

@@ -407,7 +407,7 @@ computeClangWorkingDirectory(const std::vector<std::string> &commandLineArgs,
} }
ModuleDependencyVector ModuleDependencyVector
ClangImporter::getModuleDependencies(StringRef moduleName, ClangImporter::getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
@@ -435,14 +435,14 @@ ClangImporter::getModuleDependencies(StringRef moduleName,
auto clangModuleDependencies = auto clangModuleDependencies =
clangScanningTool.getModuleDependencies( clangScanningTool.getModuleDependencies(
moduleName, commandLineArgs, workingDir, moduleName.str(), commandLineArgs, workingDir,
alreadySeenClangModules, lookupModuleOutput); alreadySeenClangModules, lookupModuleOutput);
if (!clangModuleDependencies) { if (!clangModuleDependencies) {
auto errorStr = toString(clangModuleDependencies.takeError()); auto errorStr = toString(clangModuleDependencies.takeError());
// We ignore the "module 'foo' not found" error, the Swift dependency // We ignore the "module 'foo' not found" error, the Swift dependency
// scanner will report such an error only if all of the module loaders // scanner will report such an error only if all of the module loaders
// fail as well. // fail as well.
if (errorStr.find("fatal error: module '" + moduleName.str() + if (errorStr.find("fatal error: module '" + moduleName.str().str() +
"' not found") == std::string::npos) "' not found") == std::string::npos)
ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error, ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error,
errorStr); errorStr);

View File

@@ -179,7 +179,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
ModuleDependencyVector ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForModuleDependency( ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache, Identifier moduleName, const ModuleDependenciesCache &cache,
bool isTestableImport) { bool isTestableImport) {
// First query a Swift module, otherwise lookup a Clang module // First query a Swift module, otherwise lookup a Clang module
ModuleDependencyVector moduleDependencies = ModuleDependencyVector moduleDependencies =
@@ -203,7 +203,7 @@ ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(
ModuleDependencyVector ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency( ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache) { Identifier moduleName, const ModuleDependenciesCache &cache) {
return swiftScannerModuleLoader->getModuleDependencies( return swiftScannerModuleLoader->getModuleDependencies(
moduleName, cache.getModuleOutputPath(), moduleName, cache.getModuleOutputPath(),
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(), cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
@@ -213,7 +213,7 @@ ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(
ModuleDependencyVector ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency( ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache) { Identifier moduleName, const ModuleDependenciesCache &cache) {
return clangScannerModuleLoader->getModuleDependencies( return clangScannerModuleLoader->getModuleDependencies(
moduleName, cache.getModuleOutputPath(), moduleName, cache.getModuleOutputPath(),
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(), cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
@@ -252,6 +252,10 @@ auto ModuleDependencyScanner::withDependencyScanningWorker(Function &&F,
return result; return result;
} }
Identifier ModuleDependencyScanner::getModuleImportIdentifier(StringRef moduleName) {
return ScanASTContext.getIdentifier(moduleName);
}
ModuleDependencyScanner::ModuleDependencyScanner( ModuleDependencyScanner::ModuleDependencyScanner(
SwiftDependencyScanningService &ScanningService, SwiftDependencyScanningService &ScanningService,
const CompilerInvocation &ScanCompilerInvocation, const CompilerInvocation &ScanCompilerInvocation,
@@ -443,10 +447,11 @@ ModuleDependencyScanner::getNamedClangModuleDependencyInfo(
return found; return found;
// Otherwise perform filesystem scan // Otherwise perform filesystem scan
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
auto moduleDependencies = withDependencyScanningWorker( auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) { [&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForClangModuleDependency( return ScanningWorker->scanFilesystemForClangModuleDependency(
moduleName, cache); moduleIdentifier, cache);
}); });
if (moduleDependencies.empty()) if (moduleDependencies.empty())
return llvm::None; return llvm::None;
@@ -474,10 +479,11 @@ ModuleDependencyScanner::getNamedSwiftModuleDependencyInfo(
return found; return found;
// Otherwise perform filesystem scan // Otherwise perform filesystem scan
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
auto moduleDependencies = withDependencyScanningWorker( auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) { [&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForSwiftModuleDependency( return ScanningWorker->scanFilesystemForSwiftModuleDependency(
moduleName, cache); moduleIdentifier, cache);
}); });
if (moduleDependencies.empty()) if (moduleDependencies.empty())
return llvm::None; return llvm::None;
@@ -552,8 +558,9 @@ void ModuleDependencyScanner::resolveImportDependencies(
// A scanning task to query a module by-name. If the module already exists // A scanning task to query a module by-name. If the module already exists
// in the cache, do nothing and return. // in the cache, do nothing and return.
auto scanForModuleDependency = [this, &cache, &moduleLookupResult]( auto scanForModuleDependency = [this, &cache, &moduleLookupResult](
StringRef moduleName, bool onlyClangModule, Identifier moduleIdentifier, bool onlyClangModule,
bool isTestable) { bool isTestable) {
auto moduleName = moduleIdentifier.str();
// If this is already in the cache, no work to do here // If this is already in the cache, no work to do here
if (onlyClangModule) { if (onlyClangModule) {
if (cache.hasDependency(moduleName, ModuleDependencyKind::Clang)) if (cache.hasDependency(moduleName, ModuleDependencyKind::Clang))
@@ -564,13 +571,13 @@ void ModuleDependencyScanner::resolveImportDependencies(
} }
auto moduleDependencies = withDependencyScanningWorker( auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName, onlyClangModule, [&cache, moduleIdentifier, onlyClangModule,
isTestable](ModuleDependencyScanningWorker *ScanningWorker) { isTestable](ModuleDependencyScanningWorker *ScanningWorker) {
return onlyClangModule return onlyClangModule
? ScanningWorker->scanFilesystemForClangModuleDependency( ? ScanningWorker->scanFilesystemForClangModuleDependency(
moduleName, cache) moduleIdentifier, cache)
: ScanningWorker->scanFilesystemForModuleDependency( : ScanningWorker->scanFilesystemForModuleDependency(
moduleName, cache, isTestable); moduleIdentifier, cache, isTestable);
}); });
moduleLookupResult.insert_or_assign(moduleName, moduleDependencies); moduleLookupResult.insert_or_assign(moduleName, moduleDependencies);
}; };
@@ -579,14 +586,14 @@ void ModuleDependencyScanner::resolveImportDependencies(
for (const auto &dependsOn : moduleDependencyInfo->getModuleImports()) { for (const auto &dependsOn : moduleDependencyInfo->getModuleImports()) {
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn; bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn); bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
ScanningThreadPool.async(scanForModuleDependency, dependsOn, ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
underlyingClangModuleLookup, isTestable); underlyingClangModuleLookup, isTestable);
} }
for (const auto &dependsOn : for (const auto &dependsOn :
moduleDependencyInfo->getOptionalModuleImports()) { moduleDependencyInfo->getOptionalModuleImports()) {
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn; bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn); bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
ScanningThreadPool.async(scanForModuleDependency, dependsOn, ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
underlyingClangModuleLookup, isTestable); underlyingClangModuleLookup, isTestable);
} }
ScanningThreadPool.wait(); ScanningThreadPool.wait();
@@ -726,15 +733,16 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
// A scanning task to query a Swift module by-name. If the module already // A scanning task to query a Swift module by-name. If the module already
// exists in the cache, do nothing and return. // exists in the cache, do nothing and return.
auto scanForSwiftDependency = [this, &cache, &swiftOverlayLookupResult]( auto scanForSwiftDependency = [this, &cache, &swiftOverlayLookupResult](
StringRef moduleName) { Identifier moduleIdentifier) {
auto moduleName = moduleIdentifier.str();
if (cache.hasDependency(moduleName, ModuleDependencyKind::SwiftInterface) || if (cache.hasDependency(moduleName, ModuleDependencyKind::SwiftInterface) ||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftBinary) || cache.hasDependency(moduleName, ModuleDependencyKind::SwiftBinary) ||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftPlaceholder)) cache.hasDependency(moduleName, ModuleDependencyKind::SwiftPlaceholder))
return; return;
auto moduleDependencies = withDependencyScanningWorker( auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) { [&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleName, return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleIdentifier,
cache); cache);
}); });
swiftOverlayLookupResult.insert_or_assign(moduleName, moduleDependencies); swiftOverlayLookupResult.insert_or_assign(moduleName, moduleDependencies);
@@ -742,7 +750,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
// Enque asynchronous lookup tasks // Enque asynchronous lookup tasks
for (const auto &clangDep : clangDependencies) for (const auto &clangDep : clangDependencies)
ScanningThreadPool.async(scanForSwiftDependency, clangDep); ScanningThreadPool.async(scanForSwiftDependency, getModuleImportIdentifier(clangDep));
ScanningThreadPool.wait(); ScanningThreadPool.wait();
// Aggregate both previously-cached and freshly-scanned module results // Aggregate both previously-cached and freshly-scanned module results

View File

@@ -155,7 +155,7 @@ void SourceLoader::loadExtensions(NominalTypeDecl *nominal,
} }
ModuleDependencyVector ModuleDependencyVector
SourceLoader::getModuleDependencies(StringRef moduleName, SourceLoader::getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules, const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,

View File

@@ -305,14 +305,14 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
} }
ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies( ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
StringRef moduleName, StringRef moduleOutputPath, Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS, llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> const llvm::DenseSet<clang::tooling::dependencies::ModuleID>
&alreadySeenClangModules, &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool, clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
InterfaceSubContextDelegate &delegate, llvm::TreePathPrefixMapper *mapper, InterfaceSubContextDelegate &delegate, llvm::TreePathPrefixMapper *mapper,
bool isTestableDependencyLookup) { bool isTestableDependencyLookup) {
ImportPath::Module::Builder builder(Ctx, moduleName, /*separator=*/'.'); ImportPath::Module::Builder builder(moduleName);
auto modulePath = builder.get(); auto modulePath = builder.get();
auto moduleId = modulePath.front().Item; auto moduleId = modulePath.front().Item;
llvm::Optional<SwiftDependencyTracker> tracker = llvm::None; llvm::Optional<SwiftDependencyTracker> tracker = llvm::None;
@@ -344,7 +344,7 @@ ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
ModuleDependencyVector moduleDependnecies; ModuleDependencyVector moduleDependnecies;
moduleDependnecies.push_back( moduleDependnecies.push_back(
std::make_pair(ModuleDependencyID{moduleName.str(), std::make_pair(ModuleDependencyID{moduleName.str().str(),
scanner->dependencies->getKind()}, scanner->dependencies->getKind()},
*(scanner->dependencies))); *(scanner->dependencies)));
return moduleDependnecies; return moduleDependnecies;