Skip to content

Commit cc0af1d

Browse files
[CAS] Allow uncached job from CAS based dependency scanning
Create a path that swift-frontend can execute an uncached job from modules built with CAS based explicit module build. The new flag -import-module-from-cas will allow an uncached build to load module from CAS, and combined with source file from real file system to build the current module. This allows quick iterations that bypasses CAS, without full dependency scanning every time in between. rdar://152441866
1 parent 7bf1b0a commit cc0af1d

File tree

7 files changed

+92
-3
lines changed

7 files changed

+92
-3
lines changed

include/swift/Basic/CASOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class CASOptions final {
3434
/// Skip replaying outputs from cache.
3535
bool CacheSkipReplay = false;
3636

37+
/// Import modules from CAS.
38+
bool ImportModuleFromCAS = false;
39+
3740
/// CASOptions
3841
clang::CASOptions CASOpts;
3942

include/swift/Frontend/Frontend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ class CompilerInvocation {
176176
}
177177

178178
bool requiresCAS() const {
179-
return CASOpts.EnableCaching || IRGenOpts.UseCASBackend;
179+
return CASOpts.EnableCaching || IRGenOpts.UseCASBackend ||
180+
CASOpts.ImportModuleFromCAS;
180181
}
181182

182183
void setClangModuleCachePath(StringRef Path) {

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ def module_can_import_version: MultiArg<["-"], "module-can-import-version", 3>,
244244
MetaVarName<"<moduleName> <version> <underlyingVersion>">,
245245
HelpText<"Specify canImport module and versions">;
246246

247+
def module_import_from_cas: Flag<["-"], "module-import-from-cas">,
248+
HelpText<"Import modules from CAS instead of file system">;
249+
247250
def disable_cross_import_overlay_search: Flag<["-"], "disable-cross-import-overlay-search">,
248251
HelpText<"Disable searching for cross import overlay file">;
249252

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ std::optional<std::vector<std::string>> ClangImporter::getClangCC1Arguments(
11811181
// to reduce the number of argument passing on the command-line and swift
11821182
// compiler can be more efficient to compute swift cache key without having
11831183
// the knowledge about clang command-line options.
1184-
if (ctx.CASOpts.EnableCaching) {
1184+
if (ctx.CASOpts.EnableCaching || ctx.CASOpts.ImportModuleFromCAS) {
11851185
CI->getCASOpts() = ctx.CASOpts.CASOpts;
11861186
// When clangImporter is used to compile (generate .pcm or .pch), need to
11871187
// inherit the include tree from swift args (last one wins) and clear the

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,8 @@ static bool ParseCASArgs(CASOptions &Opts, ArgList &Args,
798798
std::string(Value));
799799
}
800800

801+
Opts.ImportModuleFromCAS |= Args.hasArg(OPT_module_import_from_cas);
802+
801803
if (auto *A = Args.getLastArg(OPT_clang_include_tree_root))
802804
Opts.ClangIncludeTree = A->getValue();
803805
if (auto *A = Args.getLastArg(OPT_clang_include_tree_filelist))

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,8 @@ bool CompilerInstance::setUpModuleLoaders() {
810810
if (ExplicitModuleBuild ||
811811
!Invocation.getSearchPathOptions().ExplicitSwiftModuleMapPath.empty() ||
812812
!Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs.empty()) {
813-
if (Invocation.getCASOptions().EnableCaching)
813+
if (Invocation.getCASOptions().EnableCaching ||
814+
Invocation.getCASOptions().ImportModuleFromCAS)
814815
ESML = ExplicitCASModuleLoader::create(
815816
*Context, getObjectStore(), getActionCache(), getDependencyTracker(),
816817
MLM, Invocation.getSearchPathOptions().ExplicitSwiftModuleMapPath,

test/CAS/uncached-casfs.swift

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -module-cache-path %t/clang-module-cache \
5+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
6+
// RUN: -import-objc-header %t/base/Bridging.h -scanner-output-dir %t -auto-bridging-header-chaining -scanner-debug-write-output \
7+
// RUN: %t/base/test.swift %t/base/foo.swift -I %t/include -o %t/deps.json -cache-compile-job -cas-path %t/cas
8+
9+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shim.cmd
10+
// RUN: %swift_frontend_plain @%t/shim.cmd
11+
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:Dummy > %t/dummy.cmd
12+
// RUN: %swift_frontend_plain @%t/dummy.cmd
13+
14+
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json
15+
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
16+
17+
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
18+
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch
19+
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
20+
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json
21+
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
22+
23+
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd
24+
// RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd
25+
// RUN: echo "\"-disable-implicit-concurrency-module-import\"" >> %t/MyApp.cmd
26+
// RUN: echo "\"-disable-implicit-swift-modules\"" >> %t/MyApp.cmd
27+
// RUN: echo "\"-import-objc-header\"" >> %t/MyApp.cmd
28+
// RUN: echo "\"%t/base/Bridging.h\"" >> %t/MyApp.cmd
29+
// RUN: echo "\"-import-pch\"" >> %t/MyApp.cmd
30+
// RUN: echo "\"%t/bridging.pch\"" >> %t/MyApp.cmd
31+
// RUN: echo "\"-bridging-header-pch-key\"" >> %t/MyApp.cmd
32+
// RUN: echo "\"@%t/key\"" >> %t/MyApp.cmd
33+
// RUN: echo "\"-explicit-swift-module-map-file\"" >> %t/MyApp.cmd
34+
// RUN: echo "\"@%t/map.casid\"" >> %t/MyApp.cmd
35+
36+
// RUN: sed -e "s@VFS_DIR@%{/t:regex_replacement}/base@g" -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/modified@g" %t/base.yaml > %t/overlay.yaml
37+
38+
// RUN: %target-swift-frontend %t/base/test.swift %t/base/foo.swift -O -emit-module -emit-module-path %t/Test.swiftmodule -c \
39+
// RUN: -module-name Test -o %t/test.o -cas-path %t/cas @%t/MyApp.cmd -vfsoverlay %t/overlay.yaml -module-import-from-cas
40+
41+
42+
//--- base/test.swift
43+
import Dummy
44+
public func testFunc() {
45+
non_existing_func()
46+
}
47+
48+
//--- base/foo.swift
49+
public func foo() {}
50+
51+
//--- modified/test.swift
52+
import Dummy
53+
public func testFunc() {
54+
dummy()
55+
bridge()
56+
}
57+
58+
//--- base/Bridging.h
59+
void bridge(void);
60+
61+
//--- include/module.modulemap
62+
module Dummy {
63+
umbrella header "Dummy.h"
64+
}
65+
66+
//--- include/Dummy.h
67+
void dummy(void);
68+
69+
//--- base.yaml
70+
{
71+
version: 0,
72+
roots: [
73+
{
74+
type: "directory-remap",
75+
name: "VFS_DIR",
76+
external-contents: "EXTERNAL_DIR"
77+
}
78+
]
79+
}

0 commit comments

Comments
 (0)