Skip to content

Commit 8d5d758

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 68524a8 commit 8d5d758

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
@@ -1161,7 +1161,7 @@ std::optional<std::vector<std::string>> ClangImporter::getClangCC1Arguments(
11611161
// to reduce the number of argument passing on the command-line and swift
11621162
// compiler can be more efficient to compute swift cache key without having
11631163
// the knowledge about clang command-line options.
1164-
if (ctx.CASOpts.EnableCaching) {
1164+
if (ctx.CASOpts.EnableCaching || ctx.CASOpts.ImportModuleFromCAS) {
11651165
CI->getCASOpts() = ctx.CASOpts.CASOpts;
11661166
// When clangImporter is used to compile (generate .pcm or .pch), need to
11671167
// 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
@@ -800,6 +800,8 @@ static bool ParseCASArgs(CASOptions &Opts, ArgList &Args,
800800
std::string(Value));
801801
}
802802

803+
Opts.ImportModuleFromCAS |= Args.hasArg(OPT_module_import_from_cas);
804+
803805
if (auto *A = Args.getLastArg(OPT_clang_include_tree_root))
804806
Opts.ClangIncludeTree = A->getValue();
805807
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
@@ -821,7 +821,8 @@ bool CompilerInstance::setUpModuleLoaders() {
821821
if (ExplicitModuleBuild ||
822822
!Invocation.getSearchPathOptions().ExplicitSwiftModuleMapPath.empty() ||
823823
!Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs.empty()) {
824-
if (Invocation.getCASOptions().EnableCaching)
824+
if (Invocation.getCASOptions().EnableCaching ||
825+
Invocation.getCASOptions().ImportModuleFromCAS)
825826
ESML = ExplicitCASModuleLoader::create(
826827
*Context, getObjectStore(), getActionCache(), getDependencyTracker(),
827828
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)