Skip to content

Commit 482f194

Browse files
[DependencyScanning] Avoid extra cc1 arg round-trip to speed up bridging
Use the underlying compiler invocation inside module scanning result to speed up the clang module dependency bridging. This avoids converting cc1 arguments to compiler invocation and back, just to modify the cc1 arguments needed for building PCM using swift-frontend.
1 parent bb67d1e commit 482f194

File tree

2 files changed

+55
-80
lines changed

2 files changed

+55
-80
lines changed

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 18 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,6 @@ std::vector<std::string> ClangImporter::getClangDepScanningInvocationArguments(
8181
return commandLineArgs;
8282
}
8383

84-
static std::unique_ptr<llvm::PrefixMapper>
85-
getClangPrefixMapper(DependencyScanningTool &clangScanningTool,
86-
ModuleDeps &clangModuleDep,
87-
clang::CompilerInvocation &depsInvocation) {
88-
std::unique_ptr<llvm::PrefixMapper> Mapper;
89-
if (clangModuleDep.IncludeTreeID) {
90-
Mapper = std::make_unique<llvm::PrefixMapper>();
91-
} else if (clangModuleDep.CASFileSystemRootID) {
92-
assert(clangScanningTool.getCachingFileSystem());
93-
Mapper = std::make_unique<llvm::TreePathPrefixMapper>(
94-
clangScanningTool.getCachingFileSystem());
95-
}
96-
97-
if (Mapper)
98-
DepscanPrefixMapping::configurePrefixMapper(depsInvocation, *Mapper);
99-
100-
return Mapper;
101-
}
102-
10384
ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
10485
const ASTContext &ctx,
10586
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
@@ -147,63 +128,30 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
147128
// Swift frontend option for input file path (Foo.modulemap).
148129
swiftArgs.push_back(remapPath(clangModuleDep.ClangModuleMapFile));
149130

150-
// Handle VFSOverlay. If include tree is used, there is no need for overlay.
151-
if (!ctx.ClangImporterOpts.UseClangIncludeTree) {
152-
for (auto &overlay : ctx.SearchPathOpts.VFSOverlayFiles) {
153-
swiftArgs.push_back("-vfsoverlay");
154-
swiftArgs.push_back(remapPath(overlay));
155-
}
156-
}
157-
158-
// Add args reported by the scanner.
159-
160-
// Round-trip clang args to canonicalize and clear the options that swift
161-
// compiler doesn't need.
162-
clang::CompilerInvocation depsInvocation;
163-
clang::DiagnosticsEngine clangDiags(new clang::DiagnosticIDs(),
164-
new clang::DiagnosticOptions(),
165-
new clang::IgnoringDiagConsumer());
166-
167-
llvm::SmallVector<const char*> clangArgs;
168-
llvm::for_each(
169-
clangModuleDep.getBuildArguments(),
170-
[&](const std::string &Arg) { clangArgs.push_back(Arg.c_str()); });
171-
172-
bool success = clang::CompilerInvocation::CreateFromArgs(
173-
depsInvocation, clangArgs, clangDiags);
174-
(void)success;
175-
assert(success && "clang option from dep scanner round trip failed");
176-
177-
// Create a prefix mapper that matches clang's configuration.
178-
auto Mapper =
179-
getClangPrefixMapper(clangScanningTool, clangModuleDep, depsInvocation);
180-
181-
// Clear the cache key for module. The module key is computed from clang
182-
// invocation, not swift invocation.
183-
depsInvocation.getFrontendOpts().ModuleCacheKeys.clear();
184-
depsInvocation.getFrontendOpts().PathPrefixMappings.clear();
185-
depsInvocation.getFrontendOpts().OutputFile.clear();
131+
auto &invocation = clangModuleDep.getUnderlyingCompilerInvocation();
132+
// Clear some options from clang scanner.
133+
invocation.getMutFrontendOpts().ModuleCacheKeys.clear();
134+
invocation.getMutFrontendOpts().PathPrefixMappings.clear();
135+
invocation.getMutFrontendOpts().OutputFile.clear();
186136

187137
// Reset CASOptions since that should be coming from swift.
188-
depsInvocation.getCASOpts() = clang::CASOptions();
189-
depsInvocation.getFrontendOpts().CASIncludeTreeID.clear();
138+
invocation.getMutCASOpts() = clang::CASOptions();
139+
invocation.getMutFrontendOpts().CASIncludeTreeID.clear();
190140

191141
// FIXME: workaround for rdar://105684525: find the -ivfsoverlay option
192142
// from clang scanner and pass to swift.
193-
for (auto overlay : depsInvocation.getHeaderSearchOpts().VFSOverlayFiles) {
194-
if (llvm::is_contained(ctx.SearchPathOpts.VFSOverlayFiles, overlay))
195-
continue;
196-
swiftArgs.push_back("-vfsoverlay");
197-
swiftArgs.push_back(overlay);
143+
if (!ctx.ClangImporterOpts.UseClangIncludeTree) {
144+
auto &overlayFiles = invocation.getMutHeaderSearchOpts().VFSOverlayFiles;
145+
for (auto overlay : overlayFiles) {
146+
swiftArgs.push_back("-vfsoverlay");
147+
swiftArgs.push_back(overlay);
148+
}
149+
// Clear overlay files since they are forwarded from swift to clang.
150+
overlayFiles.clear();
198151
}
199152

200-
llvm::BumpPtrAllocator allocator;
201-
llvm::StringSaver saver(allocator);
202-
clangArgs.clear();
203-
depsInvocation.generateCC1CommandLine(
204-
clangArgs,
205-
[&saver](const llvm::Twine &T) { return saver.save(T).data(); });
206-
153+
// Add args reported by the scanner.
154+
auto &clangArgs = clangModuleDep.getBuildArguments();
207155
llvm::for_each(clangArgs, addClangArg);
208156

209157
// CASFileSystemRootID.
@@ -227,10 +175,7 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
227175
swiftArgs.push_back("-clang-include-tree-root");
228176
swiftArgs.push_back(IncludeTree);
229177
}
230-
231-
std::string mappedPCMPath = pcmPath;
232-
if (Mapper)
233-
Mapper->mapInPlace(mappedPCMPath);
178+
std::string mappedPCMPath = remapPath(pcmPath);
234179

235180
std::vector<LinkLibrary> LinkLibraries;
236181
for (const auto &ll : clangModuleDep.LinkLibraries)

test/ScanDependencies/preserve_used_vfs.swift

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
11
// REQUIRES: objc_interop
22
// RUN: %empty-directory(%t)
33
// RUN: %empty-directory(%t/module-cache)
4-
// RUN: %empty-directory(%t/redirects)
4+
// RUN: %empty-directory(%t/inputs)
55
// RUN: split-file %s %t
66

7-
// RUN: sed -e "s|OUT_DIR|%t/redirects|g" -e "s|IN_DIR|%S/Inputs/CHeaders|g" %t/overlay_template.yaml > %t/overlay.yaml
7+
// RUN: sed -e "s|OUT_DIR|%t/redirects|g" -e "s|IN_DIR|%t/inputs|g" %t/overlay_template.yaml > %t/overlay.yaml
88

9-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml
9+
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %t/inputs -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml
1010
// RUN: %validate-json %t/deps.json | %FileCheck %s
1111

12+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shim.cmd
13+
// RUN: %swift_frontend_plain @%t/shim.cmd
14+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Swift > %t/swift.cmd
15+
// RUN: %swift_frontend_plain @%t/swift.cmd
16+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json SwiftOnoneSupport > %t/onone.cmd
17+
// RUN: %swift_frontend_plain @%t/onone.cmd
18+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:F > %t/F.cmd
19+
// RUN: %swift_frontend_plain @%t/F.cmd
20+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json F > %t/SwiftF.cmd
21+
// RUN: %swift_frontend_plain @%t/SwiftF.cmd
22+
23+
// RUN: %{python} %S/../CAS/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json
24+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd
25+
// RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd
26+
// RUN: echo "\"-disable-implicit-concurrency-module-import\"" >> %t/MyApp.cmd
27+
// RUN: echo "\"-disable-implicit-swift-modules\"" >> %t/MyApp.cmd
28+
// RUN: echo "\"-explicit-swift-module-map-file\"" >> %t/MyApp.cmd
29+
// RUN: echo "\"%t/map.json\"" >> %t/MyApp.cmd
30+
31+
// RUN: %target-swift-frontend @%t/MyApp.cmd %t/test.swift -Xcc -ivfsoverlay -Xcc %t/overlay.yaml \
32+
// RUN: -emit-module -o %t/Test.swiftmodule
33+
1234
//--- redirects/RedirectedF.h
1335
void funcRedirectedF(void);
1436

37+
//--- redirects/modulemap
38+
module F {
39+
header "F_2.h"
40+
export *
41+
}
42+
1543
//--- overlay_template.yaml
1644
{
1745
'version': 0,
@@ -20,8 +48,11 @@ void funcRedirectedF(void);
2048
{
2149
'name': 'IN_DIR', 'type': 'directory',
2250
'contents': [
23-
{ 'name': 'F.h', 'type': 'file',
51+
{ 'name': 'F_2.h', 'type': 'file',
2452
'external-contents': 'OUT_DIR/RedirectedF.h'
53+
},
54+
{ 'name': 'module.modulemap', 'type': 'file',
55+
'external-contents': 'OUT_DIR/modulemap'
2556
}
2657
]
2758
},
@@ -31,6 +62,8 @@ void funcRedirectedF(void);
3162
//--- test.swift
3263
import F
3364

65+
func testF() { funcRedirectedF() }
66+
3467
// CHECK: "mainModuleName": "deps"
3568
/// --------Main module
3669
// CHECK-LABEL: "modulePath": "deps.swiftmodule",
@@ -68,7 +101,4 @@ import F
68101
// CHECK: "commandLine": [
69102
// CHECK: "-vfsoverlay",
70103
// CHECK-NEXT: "{{.*}}{{/|\\}}preserve_used_vfs.swift.tmp{{/|\\}}overlay.yaml",
71-
// CHECK: "-ivfsoverlay",
72-
// CHECK-NEXT: "-Xcc",
73-
// CHECK-NEXT: "{{.*}}{{/|\\}}preserve_used_vfs.swift.tmp{{/|\\}}overlay.yaml",
74104
// CHECK: ],

0 commit comments

Comments
 (0)