ModuleInterface: teach -compile-module-from-interface to emit forwarding module

-compile-module-from-interface action now takes arguments of -candidate-module-file.
If one of the candidate module files is up-to-date, the action emits a forwarding
module pointing to the candidate module instead of building a binary module.
This commit is contained in:
Xi Ge
2020-07-17 23:48:43 -07:00
parent 5e9934c333
commit f9396f2812
9 changed files with 105 additions and 7 deletions

View File

@@ -1029,7 +1029,6 @@ ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleN
dependencyTracker,
llvm::is_contained(PreferInterfaceForModules, moduleName) ?
ModuleLoadingMode::PreferInterface : LoadMode);
SmallVector<FileDependency, 16> allDeps;
std::vector<std::string> results;
auto pair = Impl.getCompiledModuleCandidates();
// Add compiled module candidates only when they are non-empty.
@@ -1040,6 +1039,41 @@ ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleN
return results;
}
bool ModuleInterfaceLoader::tryEmitForwardingModule(StringRef moduleName,
StringRef interfacePath,
ArrayRef<std::string> candidates,
StringRef outputPath) {
// Derive .swiftmodule path from the .swiftinterface path.
auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
llvm::SmallString<32> modulePath = interfacePath;
llvm::sys::path::replace_extension(modulePath, newExt);
ModuleInterfaceLoaderImpl Impl(
Ctx, modulePath, interfacePath, moduleName,
CacheDir, PrebuiltCacheDir, SourceLoc(),
Opts,
dependencyTracker,
llvm::is_contained(PreferInterfaceForModules, moduleName) ?
ModuleLoadingMode::PreferInterface : LoadMode);
SmallVector<FileDependency, 16> deps;
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
for (auto mod: candidates) {
// Check if the candidate compiled module is still up-to-date.
if (Impl.swiftModuleIsUpToDate(mod, deps, moduleBuffer)) {
// If so, emit a forwarding module to the candidate.
ForwardingModule FM(mod);
auto hadError = withOutputFile(Ctx.Diags, outputPath,
[&](llvm::raw_pwrite_stream &out) {
llvm::yaml::Output yamlWriter(out);
yamlWriter << FM;
return false;
});
if (!hadError)
return true;
}
}
return false;
}
bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
SourceManager &SourceMgr, DiagnosticEngine &Diags,
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
@@ -1069,7 +1103,8 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
// FIXME: We really only want to serialize 'important' dependencies here, if
// we want to ship the built swiftmodules to another machine.
return builder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
/*ModuleBuffer*/nullptr);
/*ModuleBuffer*/nullptr, nullptr,
SearchPathOpts.CandidateCompiledModules);
}
void ModuleInterfaceLoader::collectVisibleTopLevelModuleNames(