Skip to content

ModuleInterface: refactor a utility function out for collecting candidate compiled modules. NFC #32935

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
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
101 changes: 58 additions & 43 deletions lib/Frontend/ModuleInterfaceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,8 @@ class ModuleInterfaceLoaderImpl {
return path.startswith(resourceDir);
}

llvm::ErrorOr<DiscoveredModule>
discoverUpToDateCompiledModuleForInterface(SmallVectorImpl<FileDependency> &deps,
std::string &UsableModulePath) {
auto notFoundError =
std::make_error_code(std::errc::no_such_file_or_directory);

std::pair<std::string, std::string> getCompiledModuleCandidates() {
std::pair<std::string, std::string> result;
// Keep track of whether we should attempt to load a .swiftmodule adjacent
// to the .swiftinterface.
bool shouldLoadAdjacentModule = true;
Expand All @@ -604,7 +600,7 @@ class ModuleInterfaceLoaderImpl {
case ModuleLoadingMode::OnlyInterface:
// Always skip both the caches and adjacent modules, and always build the
// module interface.
return notFoundError;
return {};
case ModuleLoadingMode::PreferInterface:
// If we're in the load mode that prefers .swiftinterfaces, specifically
// skip the module adjacent to the interface, but use the caches if
Expand All @@ -627,16 +623,48 @@ class ModuleInterfaceLoaderImpl {
// diagnose it.

if (shouldLoadAdjacentModule) {
auto adjacentModuleBuffer = fs.getBufferForFile(modulePath);
if (fs.exists(modulePath)) {
result.first = modulePath;
}
}

// If we have a prebuilt cache path, check that too if the interface comes
// from the SDK.
if (!prebuiltCacheDir.empty()) {
llvm::SmallString<256> scratch;
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
Optional<StringRef> path = computePrebuiltModulePath(scratch);
if (!path) {
// Hack: deal with prebuilds of modules that still use the target-based
// names.
path = computeFallbackPrebuiltModulePath(scratch);
}
if (path) {
if (fs.exists(*path)) {
result.second = *path;
}
}
}

return result;
}

llvm::ErrorOr<DiscoveredModule>
discoverUpToDateCompiledModuleForInterface(SmallVectorImpl<FileDependency> &deps,
std::string &UsableModulePath) {
std::string adjacentMod, prebuiltMod;
std::tie(adjacentMod, prebuiltMod) = getCompiledModuleCandidates();
if (!adjacentMod.empty()) {
auto adjacentModuleBuffer = fs.getBufferForFile(adjacentMod);
if (adjacentModuleBuffer) {
if (serializedASTBufferIsUpToDate(modulePath, *adjacentModuleBuffer.get(),
if (serializedASTBufferIsUpToDate(adjacentMod, *adjacentModuleBuffer.get(),
deps)) {
LLVM_DEBUG(llvm::dbgs() << "Found up-to-date module at "
<< modulePath
<< adjacentMod
<< "; deferring to serialized module loader\n");
UsableModulePath = modulePath.str();
UsableModulePath = adjacentMod;
return std::make_error_code(std::errc::not_supported);
} else if (isInResourceDir(modulePath) &&
} else if (isInResourceDir(adjacentMod) &&
loadMode == ModuleLoadingMode::PreferSerialized) {
// Special-case here: If we're loading a .swiftmodule from the resource
// dir adjacent to the compiler, defer to the serialized loader instead
Expand All @@ -647,53 +675,40 @@ class ModuleInterfaceLoaderImpl {
// we used to.
LLVM_DEBUG(llvm::dbgs() << "Found out-of-date module in the "
"resource-dir at "
<< modulePath
<< adjacentMod
<< "; deferring to serialized module loader "
"to diagnose\n");
return std::make_error_code(std::errc::not_supported);
} else {
LLVM_DEBUG(llvm::dbgs() << "Found out-of-date module at "
<< modulePath << "\n");
rebuildInfo.setModuleKind(modulePath,
<< adjacentMod << "\n");
rebuildInfo.setModuleKind(adjacentMod,
ModuleRebuildInfo::ModuleKind::Normal);
}
} else if (adjacentModuleBuffer.getError() != notFoundError) {
} else {
LLVM_DEBUG(llvm::dbgs() << "Found unreadable module at "
<< modulePath
<< adjacentMod
<< "; deferring to serialized module loader\n");
return std::make_error_code(std::errc::not_supported);
}
}

// If we have a prebuilt cache path, check that too if the interface comes
// from the SDK.
if (!prebuiltCacheDir.empty()) {
llvm::SmallString<256> scratch;
if(!prebuiltMod.empty()) {
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
Optional<StringRef> path = computePrebuiltModulePath(scratch);
if (!path) {
// Hack: deal with prebuilds of modules that still use the target-based
// names.
path = computeFallbackPrebuiltModulePath(scratch);
}
if (path) {
if (swiftModuleIsUpToDate(*path, deps, moduleBuffer)) {
LLVM_DEBUG(llvm::dbgs() << "Found up-to-date prebuilt module at "
<< path->str() << "\n");
UsableModulePath = path->str();
return DiscoveredModule::prebuilt(*path, std::move(moduleBuffer));
} else {
LLVM_DEBUG(llvm::dbgs() << "Found out-of-date prebuilt module at "
<< path->str() << "\n");
rebuildInfo.setModuleKind(*path,
ModuleRebuildInfo::ModuleKind::Prebuilt);
}
if (swiftModuleIsUpToDate(prebuiltMod, deps, moduleBuffer)) {
LLVM_DEBUG(llvm::dbgs() << "Found up-to-date prebuilt module at "
<< prebuiltMod << "\n");
UsableModulePath = prebuiltMod;
return DiscoveredModule::prebuilt(prebuiltMod, std::move(moduleBuffer));
} else {
LLVM_DEBUG(llvm::dbgs() << "Found out-of-date prebuilt module at "
<< prebuiltMod << "\n");
rebuildInfo.setModuleKind(prebuiltMod,
ModuleRebuildInfo::ModuleKind::Prebuilt);
}
}

// Couldn't find an up-to-date .swiftmodule, will need to build module from
// interface.
return notFoundError;
// We cannot find any proper compiled module to use.
return std::make_error_code(std::errc::no_such_file_or_directory);
}

/// Finds the most appropriate .swiftmodule, whose dependencies are up to
Expand Down