Skip to content

Commit 0e12f20

Browse files
[ScanDependency] Move binary module validation into scanner
Improve swift dependency scanner by validating and selecting dependency module into scanner. This provides benefits that: * Build system does not need to schedule interface compilation task if the candidate module is picked, it can just use the candidate module directly. * There is no need for forwarding module in the explicit module build. Since the build system is coordinating the build, there is no need for the forwarding module in the module cache to avoid duplicated work, * This also correctly supports all the module loading modes in the dependency scanner. This is achieved by only adding validate and up-to-date binary module as the candidate module for swift interface module dependency. This allows caching build to construct the correct dependency in the CAS. If there is a candidate module for the interface module, dependency scanner will return a binary module dependency in the dependency graph. The legacy behavior is mostly preserved with a hidden frontend flag `-no-scanner-module-validation`, while the scanner output is mostly interchangeable with new scanner behavior with `prefer-interface` module loading mode except the candidate module will not be returned. rdar://123711823
1 parent ac1ce06 commit 0e12f20

File tree

54 files changed

+282
-190
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+282
-190
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,12 @@ class ModuleDependenciesCache {
11151115
std::optional<const ModuleDependencyInfo *>
11161116
findDependency(StringRef moduleName) const;
11171117

1118+
/// Look for known existing dependencies.
1119+
///
1120+
/// \returns the cached result.
1121+
const ModuleDependencyInfo &
1122+
findKnownDependency(const ModuleDependencyID &moduleID) const;
1123+
11181124
/// Record dependencies for the given module.
11191125
void recordDependency(StringRef moduleName,
11201126
ModuleDependencyInfo dependencies);

include/swift/AST/SearchPathOptions.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ enum class ModuleSearchPathKind {
3838
RuntimeLibrary,
3939
};
4040

41+
/// Specifies how to load modules when both a module interface and serialized
42+
/// AST are present, or whether to disallow one format or the other altogether.
43+
enum class ModuleLoadingMode {
44+
PreferInterface,
45+
PreferSerialized,
46+
OnlyInterface,
47+
OnlySerialized
48+
};
49+
4150
/// A single module search path that can come from different sources, e.g.
4251
/// framework search paths, import search path etc.
4352
class ModuleSearchPath : public llvm::RefCountedBase<ModuleSearchPath> {
@@ -499,6 +508,12 @@ class SearchPathOptions {
499508
/// original form.
500509
PathObfuscator DeserializedPathRecoverer;
501510

511+
/// Specify the module loading behavior of the compilation.
512+
ModuleLoadingMode ModuleLoadMode = ModuleLoadingMode::PreferSerialized;
513+
514+
/// Legacy scanner search behavior.
515+
bool NoScannerModuleValidation = false;
516+
502517
/// Return all module search paths that (non-recursively) contain a file whose
503518
/// name is in \p Filenames.
504519
SmallVector<const ModuleSearchPath *, 4>
@@ -546,7 +561,9 @@ class SearchPathOptions {
546561
RuntimeResourcePath,
547562
hash_combine_range(RuntimeLibraryImportPaths.begin(),
548563
RuntimeLibraryImportPaths.end()),
549-
DisableModulesValidateSystemDependencies);
564+
DisableModulesValidateSystemDependencies,
565+
NoScannerModuleValidation,
566+
ModuleLoadMode);
550567
}
551568

552569
/// Return a hash code of any components from these options that should

include/swift/Option/FrontendOptions.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,4 +1348,10 @@ def disable_strict_concurrency_region_based_isolation : Flag<["-"],
13481348
HelpText<"Disable region based isolation when running with strict concurrency enabled. Only enabled with asserts">,
13491349
Flags<[HelpHidden]>;
13501350

1351+
def no_scanner_module_validation: Flag<["-"], "no-scanner-module-validation">,
1352+
HelpText<"Do not validate binary modules in scanner and delegate the validation to swift-frontend">;
1353+
def module_load_mode: Separate<["-"], "module-load-mode">,
1354+
MetaVarName<"only-interface|prefer-interface|prefer-serialized|only-serialized">,
1355+
HelpText<"Module loading mode">;
1356+
13511357
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/FileUnit.h"
1717
#include "swift/AST/Module.h"
1818
#include "swift/AST/ModuleLoader.h"
19+
#include "swift/AST/SearchPathOptions.h"
1920
#include "llvm/Support/MemoryBuffer.h"
2021
#include "llvm/Support/PrefixMapper.h"
2122
#include "llvm/TargetParser/Triple.h"
@@ -28,15 +29,6 @@ namespace file_types {
2829
enum ID : uint8_t;
2930
}
3031

31-
/// Specifies how to load modules when both a module interface and serialized
32-
/// AST are present, or whether to disallow one format or the other altogether.
33-
enum class ModuleLoadingMode {
34-
PreferInterface,
35-
PreferSerialized,
36-
OnlyInterface,
37-
OnlySerialized
38-
};
39-
4032
/// How a dependency should be loaded.
4133
///
4234
/// \sa getTransitiveLoadingBehavior

lib/AST/ModuleDependencies.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,13 @@ ModuleDependenciesCache::findDependency(StringRef moduleName) const {
740740
return std::nullopt;
741741
}
742742

743+
const ModuleDependencyInfo &ModuleDependenciesCache::findKnownDependency(
744+
const ModuleDependencyID &moduleID) const {
745+
auto dep = findDependency(moduleID);
746+
assert(dep && "dependency unknown");
747+
return **dep;
748+
}
749+
743750
bool ModuleDependenciesCache::hasDependency(const ModuleDependencyID &moduleID) const {
744751
return hasDependency(moduleID.ModuleName, moduleID.Kind);
745752
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
174174
ScanASTContext,
175175
*static_cast<ModuleInterfaceCheckerImpl *>(
176176
ScanASTContext.getModuleInterfaceChecker()),
177-
&DependencyTracker, ModuleLoadingMode::OnlyInterface);
177+
&DependencyTracker,
178+
ScanCompilerInvocation.getSearchPathOptions().ModuleLoadMode);
178179
}
179180

180181
ModuleDependencyVector

0 commit comments

Comments
 (0)