Skip to content

Commit a2dc674

Browse files
committed
[Dependency Scanning] Disable validation of Swift dependency modules' existing pre-built candidate binary module files in the scanner, on a non-caching build.
As-is, this default interferes with the incremental build machinery which conservatively assumes that binary module dependencies must cause dependents to be re-built.
1 parent 741cd47 commit a2dc674

9 files changed

+28
-23
lines changed

Diff for: include/swift/AST/SearchPathOptions.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,9 @@ class SearchPathOptions {
542542
/// Specify the module loading behavior of the compilation.
543543
ModuleLoadingMode ModuleLoadMode = ModuleLoadingMode::PreferSerialized;
544544

545-
/// Legacy scanner search behavior.
546-
bool NoScannerModuleValidation = false;
545+
/// New scanner search behavior. Validate up-to-date existing Swift module
546+
/// dependencies in the scanner itself.
547+
bool ScannerModuleValidation = false;
547548

548549
/// Return all module search paths that (non-recursively) contain a file whose
549550
/// name is in \p Filenames.
@@ -593,7 +594,7 @@ class SearchPathOptions {
593594
hash_combine_range(RuntimeLibraryImportPaths.begin(),
594595
RuntimeLibraryImportPaths.end()),
595596
DisableModulesValidateSystemDependencies,
596-
NoScannerModuleValidation,
597+
ScannerModuleValidation,
597598
ModuleLoadMode);
598599
}
599600

Diff for: include/swift/Option/FrontendOptions.td

+2
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,8 @@ def disable_sending_args_and_results_with_region_isolation : Flag<["-"],
13861386
HelpText<"Disable sending args and results when region based isolation is enabled. Only enabled with asserts">,
13871387
Flags<[HelpHidden]>;
13881388

1389+
def scanner_module_validation: Flag<["-"], "scanner-module-validation">,
1390+
HelpText<"Validate binary modules in the dependency scanner">;
13891391
def no_scanner_module_validation: Flag<["-"], "no-scanner-module-validation">,
13901392
HelpText<"Do not validate binary modules in scanner and delegate the validation to swift-frontend">;
13911393
def module_load_mode: Separate<["-"], "module-load-mode">,

Diff for: lib/Frontend/CompilerInvocation.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,7 @@ static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModule
20052005

20062006
static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args,
20072007
DiagnosticEngine &Diags,
2008+
const CASOptions &CASOpts,
20082009
StringRef workingDirectory) {
20092010
using namespace options;
20102011
namespace path = llvm::sys::path;
@@ -2148,8 +2149,10 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args,
21482149
Opts.ScannerPrefixMapper.push_back(Opt.str());
21492150
}
21502151

2151-
Opts.NoScannerModuleValidation |=
2152-
Args.hasArg(OPT_no_scanner_module_validation);
2152+
// rdar://132340493 disable scanner-side validation for non-caching builds
2153+
Opts.ScannerModuleValidation |= Args.hasFlag(OPT_scanner_module_validation,
2154+
OPT_no_scanner_module_validation,
2155+
CASOpts.EnableCaching);
21532156

21542157
std::optional<std::string> forceModuleLoadingMode;
21552158
if (auto *A = Args.getLastArg(OPT_module_load_mode))
@@ -3556,7 +3559,7 @@ bool CompilerInvocation::parseArgs(
35563559
ParseSymbolGraphArgs(SymbolGraphOpts, ParsedArgs, Diags, LangOpts);
35573560

35583561
if (ParseSearchPathArgs(SearchPathOpts, ParsedArgs, Diags,
3559-
workingDirectory)) {
3562+
CASOpts, workingDirectory)) {
35603563
return true;
35613564
}
35623565

Diff for: lib/Frontend/ModuleInterfaceLoader.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,7 @@ ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(
14031403

14041404
auto validateModule = [&](StringRef modulePath) {
14051405
// Legacy behavior do not validate module.
1406-
if (Ctx.SearchPathOpts.NoScannerModuleValidation)
1406+
if (!Ctx.SearchPathOpts.ScannerModuleValidation)
14071407
return true;
14081408

14091409
// If we picked the other module already, no need to validate this one since
@@ -1922,8 +1922,7 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
19221922
searchPathOpts.PluginSearchOpts;
19231923

19241924
// Get module loading behavior options.
1925-
genericSubInvocation.getSearchPathOptions().NoScannerModuleValidation =
1926-
searchPathOpts.NoScannerModuleValidation;
1925+
genericSubInvocation.getSearchPathOptions().ScannerModuleValidation = searchPathOpts.ScannerModuleValidation;
19271926
genericSubInvocation.getSearchPathOptions().ModuleLoadMode =
19281927
searchPathOpts.ModuleLoadMode;
19291928

Diff for: lib/Serialization/ScanningLoaders.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
160160
auto compiledCandidates =
161161
getCompiledCandidates(Ctx, realModuleName.str(), InPath);
162162
if (!compiledCandidates.empty() &&
163-
!Ctx.SearchPathOpts.NoScannerModuleValidation) {
163+
Ctx.SearchPathOpts.ScannerModuleValidation) {
164164
assert(compiledCandidates.size() == 1 &&
165165
"Should only have 1 candidate module");
166166
auto BinaryDep = scanModuleFile(compiledCandidates[0], isFramework,

Diff for: lib/Serialization/SerializedModuleLoader.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
455455
isRequiredOSSAModules(), Ctx.LangOpts.SDKName,
456456
Ctx.SearchPathOpts.DeserializedPathRecoverer, loadedModuleFile);
457457

458-
if (!Ctx.SearchPathOpts.NoScannerModuleValidation) {
458+
if (Ctx.SearchPathOpts.ScannerModuleValidation) {
459459
// If failed to load, just ignore and return do not found.
460460
if (loadInfo.status != serialization::Status::Valid) {
461461
if (Ctx.LangOpts.EnableModuleLoadingRemarks)

Diff for: test/ScanDependencies/compiled_swift_modules.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foo
1010

1111
// HAS_BINARY: "swiftPrebuiltExternal": "Foo"
1212

13-
// HAS_NO_COMPILED-NOT: "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
13+
// HAS_NO_COMPILED-NOT: "compiledModulePath":{{.*}}"{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
1414

1515
// Step 1: build swift interface and swift module side by side
1616
// RUN: %target-swift-frontend -emit-module %t/Foo.swift -emit-module-path %t/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo -emit-module-interface-path %t/Foo.swiftmodule/%target-swiftinterface-name
@@ -20,7 +20,7 @@ import Foo
2020
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_COMPILED
2121

2222
/// Check scanner picked binary dependency if not requesting raw scan output.
23-
// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d
23+
// RUN: %target-swift-frontend -scan-dependencies %s -scanner-module-validation -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d
2424
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_BINARY
2525

2626
// Step 3: remove the adjacent module.
@@ -38,7 +38,7 @@ import Foo
3838
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_COMPILED
3939

4040
/// Check scanner picked binary dependency if not requesting raw scan output.
41-
// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules
41+
// RUN: %target-swift-frontend -scan-dependencies %s -scanner-module-validation -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules
4242
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_BINARY
4343

4444
// Step 6: update the interface file from where the prebuilt module cache was built.

Diff for: test/ScanDependencies/restrict-swiftmodule-to-revision.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@
1717
// RUN: -emit-module-interface-path %t/revision/Foo.swiftinterface -enable-library-evolution %t/foo.swift
1818

1919
// RUN: env SWIFT_DEBUG_FORCE_SWIFTMODULE_REVISION=1.0.0.0.1 \
20-
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -module-load-mode prefer-binary \
20+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-name Test -O -module-load-mode prefer-binary \
2121
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
2222
// RUN: %t/main.swift -o %t/deps-1.json -swift-version 5 -I %t/match
2323

2424
// RUN: %FileCheck %s --check-prefix=BINARY --input-file=%t/deps-1.json
2525

2626
// RUN: env SWIFT_DEBUG_FORCE_SWIFTMODULE_REVISION=1.0.0.0.1 \
27-
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -module-load-mode prefer-binary \
27+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-name Test -O -module-load-mode prefer-binary \
2828
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
2929
// RUN: %t/main.swift -o %t/deps-2.json -swift-version 5 -I %t/new
3030

3131
// RUN: %FileCheck %s --check-prefix=TEXTUAL --input-file=%t/deps-2.json
3232

3333
// RUN: env SWIFT_DEBUG_FORCE_SWIFTMODULE_REVISION=1.0.0.0.1 \
34-
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -module-load-mode prefer-binary \
34+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-name Test -O -module-load-mode prefer-binary \
3535
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
3636
// RUN: %t/main.swift -o %t/deps-3.json -swift-version 5 -I %t/revision
3737

Diff for: test/ScanDependencies/testable-dependencies.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// RUN: %t/A.swift
1818

1919
/// Import testable build, should use binary but no extra dependencies.
20-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name Test %t/main.swift \
20+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-serialized -module-name Test %t/main.swift \
2121
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
2222
// RUN: -o %t/deps1.json -I %t/testable -swift-version 5 -Rmodule-loading
2323
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json Test directDependencies | %FileCheck %s --check-prefix TEST1
@@ -26,15 +26,15 @@
2626
// EMPTY-NOT: B
2727

2828
/// Import regular build, should use binary.
29-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name Test %t/main.swift \
29+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-serialized -module-name Test %t/main.swift \
3030
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
3131
// RUN: -o %t/deps2.json -I %t/regular -swift-version 5 -Rmodule-loading
3232
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json Test directDependencies | %FileCheck %s --check-prefix TEST2
3333
// TEST2: "swiftPrebuiltExternal": "A"
3434
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty
3535

3636
/// Testable import testable build, should use binary, even interface is preferred.
37-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \
37+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -module-name Test %t/testable.swift \
3838
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
3939
// RUN: -o %t/deps3.json -I %t/testable -I %t/internal -swift-version 5 -Rmodule-loading
4040
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps3.json Test directDependencies | %FileCheck %s --check-prefix TEST3
@@ -43,7 +43,7 @@
4343
// TEST3-A: "swift": "B"
4444

4545
/// Testable import sees non-testable module first, keep searching.
46-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \
46+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -module-name Test %t/testable.swift \
4747
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
4848
// RUN: -o %t/deps4.json -I %t/regular -I %t/testable -I %t/internal -swift-version 5 -Rmodule-loading 2>&1 | %FileCheck %s --check-prefix WARN
4949
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps4.json Test directDependencies | %FileCheck %s --check-prefix TEST4
@@ -52,15 +52,15 @@
5252
// TEST4-A: "swift": "B"
5353

5454
/// Testable import non-testable build enable testing, warning about the finding then error out.
55-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \
55+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -module-name Test %t/testable.swift \
5656
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
5757
// RUN: -o %t/deps5.json -I %t/regular -swift-version 5 -Rmodule-loading 2>&1 | %FileCheck %s --check-prefix WARN --check-prefix ERROR
5858
// WARN: warning: ignore swiftmodule built without '-enable-testing'
5959
// ERROR: error: Unable to find module dependency: 'A'
6060

6161
/// Regular import a testable module with no interface, don't load optional dependencies.
6262
// RUN: rm %t/testable/A.swiftinterface
63-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/main.swift \
63+
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -module-name Test %t/main.swift \
6464
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
6565
// RUN: -o %t/deps6.json -I %t/testable -swift-version 5 -Rmodule-loading
6666
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps6.json Test directDependencies | %FileCheck %s --check-prefix TEST6

0 commit comments

Comments
 (0)