Skip to content

Commit cd2890a

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 (cherry picked from commit 0e12f20)
1 parent 5f78ea1 commit cd2890a

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
@@ -1097,6 +1097,12 @@ class ModuleDependenciesCache {
10971097
std::optional<const ModuleDependencyInfo *>
10981098
findDependency(StringRef moduleName) const;
10991099

1100+
/// Look for known existing dependencies.
1101+
///
1102+
/// \returns the cached result.
1103+
const ModuleDependencyInfo &
1104+
findKnownDependency(const ModuleDependencyID &moduleID) const;
1105+
11001106
/// Record dependencies for the given module.
11011107
void recordDependency(StringRef moduleName,
11021108
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
@@ -1337,4 +1337,10 @@ def disable_strict_concurrency_region_based_isolation : Flag<["-"],
13371337
HelpText<"Disable region based isolation when running with strict concurrency enabled. Only enabled with asserts">,
13381338
Flags<[HelpHidden]>;
13391339

1340+
def no_scanner_module_validation: Flag<["-"], "no-scanner-module-validation">,
1341+
HelpText<"Do not validate binary modules in scanner and delegate the validation to swift-frontend">;
1342+
def module_load_mode: Separate<["-"], "module-load-mode">,
1343+
MetaVarName<"only-interface|prefer-interface|prefer-serialized|only-serialized">,
1344+
HelpText<"Module loading mode">;
1345+
13401346
} // 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
@@ -739,6 +739,13 @@ ModuleDependenciesCache::findDependency(StringRef moduleName) const {
739739
return std::nullopt;
740740
}
741741

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

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
185185
ScanASTContext,
186186
*static_cast<ModuleInterfaceCheckerImpl *>(
187187
ScanASTContext.getModuleInterfaceChecker()),
188-
&DependencyTracker, ModuleLoadingMode::OnlyInterface);
188+
&DependencyTracker,
189+
ScanCompilerInvocation.getSearchPathOptions().ModuleLoadMode);
189190
}
190191

191192
ModuleDependencyVector

0 commit comments

Comments
 (0)