Skip to content

Commit fc16f3f

Browse files
Merge pull request #80068 from cachemeifyoucan/eng/PR-enable-deterministic-check
2 parents 7ae7371 + 6de9391 commit fc16f3f

File tree

5 files changed

+97
-3
lines changed

5 files changed

+97
-3
lines changed

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,9 +1425,6 @@ def enable_emit_generic_class_ro_t_list :
14251425
HelpText<"Enable emission of a section with references to class_ro_t of "
14261426
"generic class patterns">;
14271427

1428-
def enable_deterministic_check :
1429-
Flag<["-"], "enable-deterministic-check">,
1430-
HelpText<"Check compiler output determinism by running it twice">;
14311428
def always_compile_output_files :
14321429
Flag<["-"], "always-compile-output-files">,
14331430
HelpText<"Always compile output files even it might not change the results">;

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,4 +2245,9 @@ def disable_sandbox:
22452245
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
22462246
HelpText<"Disable using the sandbox when executing subprocesses">;
22472247

2248+
def enable_deterministic_check :
2249+
Flag<["-"], "enable-deterministic-check">,
2250+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, CacheInvariant]>,
2251+
HelpText<"Check compiler output determinism by running it twice">;
2252+
22482253
include "FrontendOptions.td"

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class ExplicitModuleDependencyResolver {
167167
bridgingHeaderBuildCmd.push_back(clangDep->moduleCacheKey);
168168
}
169169
}
170+
addDeterministicCheckFlags(bridgingHeaderBuildCmd);
170171
}
171172

172173
SwiftInterfaceModuleOutputPathResolution::ResultTy swiftInterfaceOutputPath;
@@ -183,6 +184,7 @@ class ExplicitModuleDependencyResolver {
183184
remapPathsFromCommandLine(commandline, [&](StringRef path) {
184185
return cache.getScanService().remapPath(path);
185186
});
187+
addDeterministicCheckFlags(commandline);
186188
}
187189

188190
auto dependencyInfoCopy = resolvingDepInfo;
@@ -583,6 +585,17 @@ class ExplicitModuleDependencyResolver {
583585
return llvm::Error::success();
584586
}
585587

588+
void addDeterministicCheckFlags(std::vector<std::string> &cmd) {
589+
// Propagate the deterministic check to explicit built module command.
590+
if (!instance.getInvocation().getFrontendOptions().DeterministicCheck)
591+
return;
592+
cmd.push_back("-enable-deterministic-check");
593+
cmd.push_back("-always-compile-output-files");
594+
// disable cache replay because that defeat the purpose of the check.
595+
if (instance.getInvocation().getCASOptions().EnableCaching)
596+
cmd.push_back("-cache-disable-replay");
597+
}
598+
586599
private:
587600
const ModuleDependencyID &moduleID;
588601
ModuleDependenciesCache &cache;

test/CAS/deterministic_check.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \
5+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -module-load-mode prefer-serialized \
6+
// RUN: %t/test.swift -o %t/deps.json -I %t -import-objc-header %t/Bridging.h \
7+
// RUN: -enable-deterministic-check -cache-compile-job -cas-path %t/cas 2>&1 | %FileCheck %s
8+
9+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json A > %t/A.cmd
10+
// RUN: %FileCheck %s --check-prefix=CMD --input-file=%t/A.cmd
11+
// RUN: %swift_frontend_plain @%t/A.cmd 2>&1 | %FileCheck %s
12+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:B > %t/B.cmd
13+
// RUN: %FileCheck %s --check-prefix=CMD --input-file=%t/B.cmd
14+
// RUN: %swift_frontend_plain @%t/B.cmd 2>&1 | %FileCheck %s
15+
16+
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps.json Test bridgingHeader | %FileCheck %s --check-prefix=CMD
17+
18+
// CHECK: remark: produced matching output file
19+
// CMD: -enable-deterministic-check
20+
// CMD: -always-compile-output-files
21+
// CMD: -cache-disable-replay
22+
23+
//--- test.swift
24+
import A
25+
import B
26+
public func test() {}
27+
28+
//--- A.swiftinterface
29+
// swift-interface-format-version: 1.0
30+
// swift-module-flags: -module-name A -O -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -user-module-version 1.0
31+
public func a() { }
32+
33+
//--- b.h
34+
void b(void);
35+
36+
//--- module.modulemap
37+
module B {
38+
header "b.h"
39+
export *
40+
}
41+
42+
//--- Bridging.h
43+
void bridge(void);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \
5+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -module-load-mode prefer-serialized \
6+
// RUN: %t/test.swift -o %t/deps.json -I %t -enable-deterministic-check 2>&1 | %FileCheck %s
7+
8+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json A > %t/A.cmd
9+
// RUN: %FileCheck %s --check-prefix=CMD --input-file=%t/A.cmd
10+
// RUN: %swift_frontend_plain @%t/A.cmd 2>&1 | %FileCheck %s
11+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:B > %t/B.cmd
12+
// RUN: %FileCheck %s --check-prefix=CMD --input-file=%t/B.cmd
13+
// RUN: %swift_frontend_plain @%t/B.cmd 2>&1 | %FileCheck %s
14+
15+
// CHECK: remark: produced matching output file
16+
// CMD: -enable-deterministic-check
17+
// CMD: -always-compile-output-files
18+
19+
//--- test.swift
20+
import A
21+
import B
22+
public func test() {}
23+
24+
//--- A.swiftinterface
25+
// swift-interface-format-version: 1.0
26+
// swift-module-flags: -module-name A -O -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -user-module-version 1.0
27+
public func a() { }
28+
29+
//--- b.h
30+
void b(void);
31+
32+
//--- module.modulemap
33+
module B {
34+
header "b.h"
35+
export *
36+
}

0 commit comments

Comments
 (0)