Skip to content

Commit c2c2414

Browse files
Merge pull request #65925 from cachemeifyoucan/eng/PR-swift-frontend-tweaks-for-caching
Cleanup some redundant dependencies and unnecessary works that prevent compiler caching.
2 parents 1864f12 + f4569a6 commit c2c2414

File tree

6 files changed

+45
-29
lines changed

6 files changed

+45
-29
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@ class ClangImporter final : public ClangModuleLoader {
397397
/// replica.
398398
///
399399
/// \sa clang::GeneratePCHAction
400-
bool emitBridgingPCH(StringRef headerPath, StringRef outputPCHPath);
400+
bool emitBridgingPCH(StringRef headerPath, StringRef outputPCHPath,
401+
bool cached);
401402

402403
/// Returns true if a clang CompilerInstance can successfully read in a PCH,
403404
/// assuming it exists, with the current options. This can be used to find out
@@ -529,7 +530,7 @@ class ClangImporter final : public ClangModuleLoader {
529530

530531
Optional<std::string>
531532
getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
532-
StringRef SwiftPCHHash);
533+
StringRef SwiftPCHHash, bool Cached);
533534
Optional<std::string>
534535
/// \param isExplicit true if the PCH filename was passed directly
535536
/// with -import-objc-header option.

lib/ClangImporter/ClangImporter.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ namespace {
194194
Importer.addSearchPath(path, /*isFramework*/false, /*isSystem=*/false);
195195
}
196196

197-
auto PCH = Importer.getOrCreatePCH(ImporterOpts, SwiftPCHHash);
197+
auto PCH =
198+
Importer.getOrCreatePCH(ImporterOpts, SwiftPCHHash, /*Cached=*/true);
198199
if (PCH.has_value()) {
199200
Impl.getClangInstance()->getPreprocessorOpts().ImplicitPCHInclude =
200201
PCH.value();
@@ -546,8 +547,10 @@ importer::getNormalInvocationArguments(
546547
});
547548
}
548549

549-
if (auto path = getCxxShimModuleMapPath(searchPathOpts, triple)) {
550-
invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str());
550+
if (LangOpts.EnableCXXInterop) {
551+
if (auto path = getCxxShimModuleMapPath(searchPathOpts, triple)) {
552+
invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str());
553+
}
551554
}
552555

553556
// Set C language options.
@@ -953,8 +956,9 @@ ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
953956
return PCHFilename.str().str();
954957
}
955958

956-
Optional<std::string> ClangImporter::getOrCreatePCH(
957-
const ClangImporterOptions &ImporterOptions, StringRef SwiftPCHHash) {
959+
Optional<std::string>
960+
ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
961+
StringRef SwiftPCHHash, bool Cached) {
958962
bool isExplicit;
959963
auto PCHFilename = getPCHFilename(ImporterOptions, SwiftPCHHash,
960964
isExplicit);
@@ -970,8 +974,8 @@ Optional<std::string> ClangImporter::getOrCreatePCH(
970974
<< EC.message();
971975
return None;
972976
}
973-
auto FailedToEmit =
974-
emitBridgingPCH(ImporterOptions.BridgingHeader, PCHFilename.value());
977+
auto FailedToEmit = emitBridgingPCH(ImporterOptions.BridgingHeader,
978+
PCHFilename.value(), Cached);
975979
if (FailedToEmit) {
976980
return None;
977981
}
@@ -983,9 +987,10 @@ Optional<std::string> ClangImporter::getOrCreatePCH(
983987
std::vector<std::string>
984988
ClangImporter::getClangArguments(ASTContext &ctx, bool ignoreClangTarget) {
985989
std::vector<std::string> invocationArgStrs;
986-
// Clang expects this to be like an actual command line. So we need to pass in
987-
// "clang" for argv[0]
988-
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
990+
// When creating from driver commands, clang expects this to be like an actual
991+
// command line. So we need to pass in "clang" for argv[0]
992+
if (!ctx.ClangImporterOpts.DirectClangCC1ModuleBuild)
993+
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
989994
if (ctx.ClangImporterOpts.ExtraArgsOnly) {
990995
invocationArgStrs.insert(invocationArgStrs.end(),
991996
ctx.ClangImporterOpts.ExtraArgs.begin(),
@@ -1734,13 +1739,13 @@ ClangImporter::cloneCompilerInstanceForPrecompiling() {
17341739
}
17351740

17361741
bool ClangImporter::emitBridgingPCH(
1737-
StringRef headerPath, StringRef outputPCHPath) {
1742+
StringRef headerPath, StringRef outputPCHPath, bool cached) {
17381743
auto emitInstance = cloneCompilerInstanceForPrecompiling();
17391744
auto &invocation = emitInstance->getInvocation();
17401745

17411746
auto LangOpts = invocation.getLangOpts();
17421747
LangOpts->NeededByPCHOrCompilationUsesPCH = true;
1743-
LangOpts->CacheGeneratedPCH = true;
1748+
LangOpts->CacheGeneratedPCH = cached;
17441749

17451750
auto language = getLanguageFromOptions(LangOpts);
17461751
auto inputFile = clang::FrontendInputFile(headerPath, language);
@@ -1991,12 +1996,16 @@ ModuleDecl *ClangImporter::Implementation::loadModuleClang(
19911996
auto &clangHeaderSearch = getClangPreprocessor().getHeaderSearchInfo();
19921997
auto realModuleName = SwiftContext.getRealModuleName(path.front().Item).str();
19931998

1994-
// Look up the top-level module first, to see if it exists at all.
1995-
clang::Module *clangModule = clangHeaderSearch.lookupModule(
1996-
realModuleName, /*ImportLoc=*/clang::SourceLocation(),
1997-
/*AllowSearch=*/true, /*AllowExtraModuleMapSearch=*/true);
1998-
if (!clangModule)
1999-
return nullptr;
1999+
// For explicit module build, module should always exist but module map might
2000+
// not be exist. Go straight to module loader.
2001+
if (Instance->getInvocation().getLangOpts()->ImplicitModules) {
2002+
// Look up the top-level module first, to see if it exists at all.
2003+
clang::Module *clangModule = clangHeaderSearch.lookupModule(
2004+
realModuleName, /*ImportLoc=*/clang::SourceLocation(),
2005+
/*AllowSearch=*/true, /*AllowExtraModuleMapSearch=*/true);
2006+
if (!clangModule)
2007+
return nullptr;
2008+
}
20002009

20012010
// Convert the Swift import path over to a Clang import path.
20022011
SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4>
@@ -2051,7 +2060,7 @@ ModuleDecl *ClangImporter::Implementation::loadModuleClang(
20512060

20522061
// Now load the top-level module, so that we can check if the submodule
20532062
// exists without triggering a fatal error.
2054-
clangModule = loadModule(clangPath.front(), clang::Module::AllVisible);
2063+
auto clangModule = loadModule(clangPath.front(), clang::Module::AllVisible);
20552064
if (!clangModule)
20562065
return nullptr;
20572066

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,13 @@ static bool precompileBridgingHeader(const CompilerInstance &Instance) {
369369
if (!PCHOutDir.empty()) {
370370
// Create or validate a persistent PCH.
371371
auto SwiftPCHHash = Invocation.getPCHHash();
372-
auto PCH = clangImporter->getOrCreatePCH(ImporterOpts, SwiftPCHHash);
372+
auto PCH = clangImporter->getOrCreatePCH(ImporterOpts, SwiftPCHHash,
373+
/*cached=*/false);
373374
return !PCH.has_value();
374375
}
375376
return clangImporter->emitBridgingPCH(
376377
opts.InputsAndOutputs.getFilenameOfFirstInput(),
377-
opts.InputsAndOutputs.getSingleOutputFilename());
378+
opts.InputsAndOutputs.getSingleOutputFilename(), /*cached=*/false);
378379
}
379380

380381
static bool precompileClangModule(const CompilerInstance &Instance) {
@@ -2072,6 +2073,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
20722073
auto finishDiagProcessing = [&](int retValue, bool verifierEnabled) -> int {
20732074
FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true;
20742075
PDC.setSuppressOutput(false);
2076+
if (auto *CDP = Instance->getCachingDiagnosticsProcessor()) {
2077+
// Don't cache if build failed.
2078+
if (retValue)
2079+
CDP->endDiagnosticCapture();
2080+
}
20752081
bool diagnosticsError = Instance->getDiags().finishProcessing();
20762082
// If the verifier is enabled and did not encounter any verification errors,
20772083
// return 0 even if the compile failed. This behavior isn't ideal, but large
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: not %target-swift-frontend -emit-module -emit-module-path %t/test.module \
2+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/test.module \
33
// RUN: -enable-cas -cas-path %t/cas -allow-unstable-cache-key-for-testing %s 2>&1 | %FileCheck %s
44
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
55
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/test.module -enable-cas -cas-path %t/cas \
@@ -9,7 +9,7 @@
99
// RUN: -allow-unstable-cache-key-for-testing %s 2>&1 | %FileCheck %s
1010

1111
#sourceLocation(file: "anything.swift", line: 1)
12-
func 1() {}
12+
#warning("this is a warning")
1313
#sourceLocation()
1414

15-
// CHECK: anything.swift:1:6: error: function name
15+
// CHECK: anything.swift:1:10: warning: this is a warning

test/ClangImporter/pcm-emit-direct-cc1-mode.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// CHECK-DUMP: Module map file: {{.*[/\\]}}Inputs{{/|\\}}custom-modules{{/|\\}}module.map
1010

1111
// Verify that the clang command-line used is cc1
12-
// RUN: %FileCheck -check-prefix CHECK-CLANG %s < %t.diags.txt
13-
// CHECK-CLANG: '{{.*[/\\]}}clang'{{.*}}'-fmodules'
12+
// RUN: %FileCheck -check-prefix CHECK-CLANG -DTRIPLE=%target-triple %s < %t.diags.txt
13+
// CHECK-CLANG: '{{.*[/\\]}}module.map' '-o' '{{.*[/\\]}}script.pcm' '-fmodules' '-triple' '[[TRIPLE]]' '-x' 'objective-c'
1414

1515
import script
1616
var _ : ScriptTy

unittests/ClangImporter/ClangImporterTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ TEST(ClangImporterTest, emitPCHInMemory) {
8686

8787
std::string PCH = createFilename(cache, "bridging.h.pch");
8888
ASSERT_FALSE(importer->canReadPCH(PCH));
89-
ASSERT_FALSE(importer->emitBridgingPCH(options.BridgingHeader, PCH));
89+
ASSERT_FALSE(importer->emitBridgingPCH(options.BridgingHeader, PCH, true));
9090
ASSERT_TRUE(importer->canReadPCH(PCH));
9191

9292
// Overwrite the PCH with garbage. We should still be able to read it from

0 commit comments

Comments
 (0)