Skip to content

[Dependency Scanning] Remove/move mutable state from parallel scanner workers #70211

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 2 commits into from
Dec 15, 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
4 changes: 0 additions & 4 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -915,10 +915,6 @@ class SwiftDependencyScanningService {
return Mapper->mapToString(Path);
}

/// Wrap the filesystem on the specified `CompilerInstance` with a
/// caching `DependencyScanningWorkerFilesystem`
void overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance);

/// Setup caching service.
bool setupCachingDependencyScanningService(CompilerInstance &Instance);
private:
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/ModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class ModuleLoader {
/// Retrieve the dependencies for the given, named module, or \c None
/// if no such module exists.
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName,
getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ class ClangImporter final : public ClangModuleLoader {
StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr);

llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
Expand Down
9 changes: 6 additions & 3 deletions include/swift/DependencyScan/ModuleDependencyScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTContext.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/ModuleDependencies.h"
#include "swift/Frontend/ModuleInterfaceLoader.h"
#include "swift/Serialization/SerializedModuleLoader.h"
Expand All @@ -36,18 +37,18 @@ class ModuleDependencyScanningWorker {
private:
/// Retrieve the module dependencies for the module with the given name.
ModuleDependencyVector
scanFilesystemForModuleDependency(StringRef moduleName,
scanFilesystemForModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache,
bool isTestableImport = false);

/// Retrieve the module dependencies for the Clang module with the given name.
ModuleDependencyVector
scanFilesystemForClangModuleDependency(StringRef moduleName,
scanFilesystemForClangModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache);

/// Retrieve the module dependencies for the Swift module with the given name.
ModuleDependencyVector
scanFilesystemForSwiftModuleDependency(StringRef moduleName,
scanFilesystemForSwiftModuleDependency(Identifier moduleName,
const ModuleDependenciesCache &cache);

// An AST delegate for interface scanning.
Expand Down Expand Up @@ -135,6 +136,8 @@ class ModuleDependencyScanner {
template <typename Function, typename... Args>
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);

Identifier getModuleImportIdentifier(StringRef moduleName);

private:
const CompilerInvocation &ScanCompilerInvocation;
ASTContext &ScanASTContext;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Sema/SourceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class SourceLoader : public ModuleLoader {
}

llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/SerializedModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
virtual void verifyAllModules() override;

virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
Expand Down
11 changes: 0 additions & 11 deletions lib/AST/ModuleDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,17 +480,6 @@ SwiftDependencyTracker::createTreeFromDependencies() {
});
}

void SwiftDependencyScanningService::overlaySharedFilesystemCacheForCompilation(
CompilerInstance &Instance) {
auto existingFS = Instance.getSourceMgr().getFileSystem();
llvm::IntrusiveRefCntPtr<
clang::tooling::dependencies::DependencyScanningWorkerFilesystem>
depFS =
new clang::tooling::dependencies::DependencyScanningWorkerFilesystem(
getSharedFilesystemCache(), existingFS);
Instance.getSourceMgr().setFileSystem(depFS);
}

bool SwiftDependencyScanningService::setupCachingDependencyScanningService(
CompilerInstance &Instance) {
if (!Instance.getInvocation().getFrontendOptions().EnableCaching)
Expand Down
10 changes: 6 additions & 4 deletions lib/AST/SearchPathOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ ModuleSearchPathLookup::searchPathsContainingFile(
llvm::SmallSet<std::pair<ModuleSearchPathKind, unsigned>, 4> ResultIds;

for (auto &Filename : Filenames) {
for (auto &Entry : LookupTable.lookup(Filename)) {
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
.second) {
Result.push_back(Entry.get());
if (LookupTable.contains(Filename)) {
for (auto &Entry : LookupTable.at(Filename)) {
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
.second) {
Result.push_back(Entry.get());
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/ClangImporter/ClangModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ computeClangWorkingDirectory(const std::vector<std::string> &commandLineArgs,
}

ModuleDependencyVector
ClangImporter::getModuleDependencies(StringRef moduleName,
ClangImporter::getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
Expand Down Expand Up @@ -435,14 +435,14 @@ ClangImporter::getModuleDependencies(StringRef moduleName,

auto clangModuleDependencies =
clangScanningTool.getModuleDependencies(
moduleName, commandLineArgs, workingDir,
moduleName.str(), commandLineArgs, workingDir,
alreadySeenClangModules, lookupModuleOutput);
if (!clangModuleDependencies) {
auto errorStr = toString(clangModuleDependencies.takeError());
// We ignore the "module 'foo' not found" error, the Swift dependency
// scanner will report such an error only if all of the module loaders
// 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)
ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error,
errorStr);
Expand Down
42 changes: 25 additions & 17 deletions lib/DependencyScan/ModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(

ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache,
Identifier moduleName, const ModuleDependenciesCache &cache,
bool isTestableImport) {
// First query a Swift module, otherwise lookup a Clang module
ModuleDependencyVector moduleDependencies =
Expand All @@ -203,7 +203,7 @@ ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(

ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache) {
Identifier moduleName, const ModuleDependenciesCache &cache) {
return swiftScannerModuleLoader->getModuleDependencies(
moduleName, cache.getModuleOutputPath(),
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
Expand All @@ -213,7 +213,7 @@ ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(

ModuleDependencyVector
ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency(
StringRef moduleName, const ModuleDependenciesCache &cache) {
Identifier moduleName, const ModuleDependenciesCache &cache) {
return clangScannerModuleLoader->getModuleDependencies(
moduleName, cache.getModuleOutputPath(),
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
Expand Down Expand Up @@ -252,6 +252,10 @@ auto ModuleDependencyScanner::withDependencyScanningWorker(Function &&F,
return result;
}

Identifier ModuleDependencyScanner::getModuleImportIdentifier(StringRef moduleName) {
return ScanASTContext.getIdentifier(moduleName);
}

ModuleDependencyScanner::ModuleDependencyScanner(
SwiftDependencyScanningService &ScanningService,
const CompilerInvocation &ScanCompilerInvocation,
Expand Down Expand Up @@ -443,10 +447,11 @@ ModuleDependencyScanner::getNamedClangModuleDependencyInfo(
return found;

// Otherwise perform filesystem scan
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForClangModuleDependency(
moduleName, cache);
moduleIdentifier, cache);
});
if (moduleDependencies.empty())
return llvm::None;
Expand Down Expand Up @@ -474,10 +479,11 @@ ModuleDependencyScanner::getNamedSwiftModuleDependencyInfo(
return found;

// Otherwise perform filesystem scan
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForSwiftModuleDependency(
moduleName, cache);
moduleIdentifier, cache);
});
if (moduleDependencies.empty())
return llvm::None;
Expand Down Expand Up @@ -552,8 +558,9 @@ void ModuleDependencyScanner::resolveImportDependencies(
// A scanning task to query a module by-name. If the module already exists
// in the cache, do nothing and return.
auto scanForModuleDependency = [this, &cache, &moduleLookupResult](
StringRef moduleName, bool onlyClangModule,
Identifier moduleIdentifier, bool onlyClangModule,
bool isTestable) {
auto moduleName = moduleIdentifier.str();
// If this is already in the cache, no work to do here
if (onlyClangModule) {
if (cache.hasDependency(moduleName, ModuleDependencyKind::Clang))
Expand All @@ -564,13 +571,13 @@ void ModuleDependencyScanner::resolveImportDependencies(
}

auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName, onlyClangModule,
[&cache, moduleIdentifier, onlyClangModule,
isTestable](ModuleDependencyScanningWorker *ScanningWorker) {
return onlyClangModule
? ScanningWorker->scanFilesystemForClangModuleDependency(
moduleName, cache)
moduleIdentifier, cache)
: ScanningWorker->scanFilesystemForModuleDependency(
moduleName, cache, isTestable);
moduleIdentifier, cache, isTestable);
});
moduleLookupResult.insert_or_assign(moduleName, moduleDependencies);
};
Expand All @@ -579,14 +586,14 @@ void ModuleDependencyScanner::resolveImportDependencies(
for (const auto &dependsOn : moduleDependencyInfo->getModuleImports()) {
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
ScanningThreadPool.async(scanForModuleDependency, dependsOn,
ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
underlyingClangModuleLookup, isTestable);
}
for (const auto &dependsOn :
moduleDependencyInfo->getOptionalModuleImports()) {
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
ScanningThreadPool.async(scanForModuleDependency, dependsOn,
ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
underlyingClangModuleLookup, isTestable);
}
ScanningThreadPool.wait();
Expand Down Expand Up @@ -726,23 +733,24 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
// A scanning task to query a Swift module by-name. If the module already
// exists in the cache, do nothing and return.
auto scanForSwiftDependency = [this, &cache, &swiftOverlayLookupResult](
StringRef moduleName) {
Identifier moduleIdentifier) {
auto moduleName = moduleIdentifier.str();
if (cache.hasDependency(moduleName, ModuleDependencyKind::SwiftInterface) ||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftBinary) ||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftPlaceholder))
return;

auto moduleDependencies = withDependencyScanningWorker(
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleName,
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleIdentifier,
cache);
});
swiftOverlayLookupResult.insert_or_assign(moduleName, moduleDependencies);
};

// Enque asynchronous lookup tasks
for (const auto &clangDep : clangDependencies)
ScanningThreadPool.async(scanForSwiftDependency, clangDep);
ScanningThreadPool.async(scanForSwiftDependency, getModuleImportIdentifier(clangDep));
ScanningThreadPool.wait();

// Aggregate both previously-cached and freshly-scanned module results
Expand Down
3 changes: 0 additions & 3 deletions lib/DependencyScan/ScanDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,8 +1448,6 @@ bool swift::dependencies::scanDependencies(CompilerInstance &instance) {
if (opts.ReuseDependencyScannerCache)
deserializeDependencyCache(instance, service);

// Wrap the filesystem with a caching `DependencyScanningWorkerFilesystem`
service.overlaySharedFilesystemCacheForCompilation(instance);
if (service.setupCachingDependencyScanningService(instance))
return true;

Expand Down Expand Up @@ -1520,7 +1518,6 @@ bool swift::dependencies::batchScanDependencies(
// we have created

SwiftDependencyScanningService singleUseService;
singleUseService.overlaySharedFilesystemCacheForCompilation(instance);
if (singleUseService.setupCachingDependencyScanningService(instance))
return true;

Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/SourceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void SourceLoader::loadExtensions(NominalTypeDecl *nominal,
}

ModuleDependencyVector
SourceLoader::getModuleDependencies(StringRef moduleName,
SourceLoader::getModuleDependencies(Identifier moduleName,
StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
Expand Down
6 changes: 3 additions & 3 deletions lib/Serialization/ScanningLoaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,14 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
}

ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
StringRef moduleName, StringRef moduleOutputPath,
Identifier moduleName, StringRef moduleOutputPath,
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
const llvm::DenseSet<clang::tooling::dependencies::ModuleID>
&alreadySeenClangModules,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
InterfaceSubContextDelegate &delegate, llvm::TreePathPrefixMapper *mapper,
bool isTestableDependencyLookup) {
ImportPath::Module::Builder builder(Ctx, moduleName, /*separator=*/'.');
ImportPath::Module::Builder builder(moduleName);
auto modulePath = builder.get();
auto moduleId = modulePath.front().Item;
llvm::Optional<SwiftDependencyTracker> tracker = llvm::None;
Expand Down Expand Up @@ -344,7 +344,7 @@ ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(

ModuleDependencyVector moduleDependnecies;
moduleDependnecies.push_back(
std::make_pair(ModuleDependencyID{moduleName.str(),
std::make_pair(ModuleDependencyID{moduleName.str().str(),
scanner->dependencies->getKind()},
*(scanner->dependencies)));
return moduleDependnecies;
Expand Down