Skip to content

Commit b5c6005

Browse files
[CAS] Add a mode to load PCMs built from CAS into regular compilation
Usually, the PCMs and PCHs built from CAS are built to be used by other CAS enabled compilation tasks, thus it has additional steps to implicitly load dependencies from the CAS. Add a new option to allow a regular compilation instance to load the modules built from CAS by ignoring the CAS info inside the serialized AST. This allows tools like debugger to directly importing the PCMs without the need to access the CAS. In order to use this option, all dependencies modules need to be load explicitly.
1 parent c97ba62 commit b5c6005

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7106,6 +7106,11 @@ def fcas_include_tree : Separate<["-"], "fcas-include-tree">,
71067106
HelpText<"Configure the frontend to use a CAS include tree.">,
71077107
MarshallingInfoString<FrontendOpts<"CASIncludeTreeID">>;
71087108

7109+
defm module_load_ignore_cas : BoolFOption<"module-load-ignore-cas",
7110+
FrontendOpts<"ModuleLoadIgnoreCAS">, DefaultFalse,
7111+
PosFlag<SetTrue, [], "Ignore CAS info when loading modules or PCHs">,
7112+
NegFlag<SetFalse>>;
7113+
71097114
// FIXME: Add to driver under -fexperimental-cache=compile-job.
71107115
defm cache_compile_job : BoolFOption<"cache-compile-job",
71117116
FrontendOpts<"CacheCompileJob">, DefaultFalse,

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ class CompilerInstance : public ModuleLoader {
758758
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
759759
void *DeserializationListener, bool OwnDeserializationListener,
760760
bool Preamble, bool UseGlobalModuleIndex,
761-
cas::ObjectStore &CAS, cas::ActionCache &Cache,
761+
cas::ObjectStore &CAS, cas::ActionCache &Cache, bool ignoreCAS,
762762
std::unique_ptr<llvm::MemoryBuffer> PCHBuffer = nullptr);
763763

764764
/// Create a code completion consumer using the invocation; note that this

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,9 @@ class FrontendOptions {
488488
/// Use the provided CAS include tree.
489489
std::string CASIncludeTreeID;
490490

491+
/// If ignore all the CAS info from serialized AST like modules and PCHs.
492+
bool ModuleLoadIgnoreCAS = false;
493+
491494
/// When the input is a module map, the original module map file from which
492495
/// that map was inferred, if any (for umbrella modules).
493496
std::string OriginalModuleMap;

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,9 @@ void CompilerInstance::createPCHExternalASTSource(
676676
getASTContext(), getPCHContainerReader(),
677677
getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
678678
DeserializationListener, OwnDeserializationListener, Preamble,
679-
getFrontendOpts().UseGlobalModuleIndex,
680-
getOrCreateObjectStore(), getOrCreateActionCache(), std::move(PCHBuffer));
679+
getFrontendOpts().UseGlobalModuleIndex, getOrCreateObjectStore(),
680+
getOrCreateActionCache(), getFrontendOpts().ModuleLoadIgnoreCAS,
681+
std::move(PCHBuffer));
681682
}
682683

683684
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
@@ -690,7 +691,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
690691
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
691692
void *DeserializationListener, bool OwnDeserializationListener,
692693
bool Preamble, bool UseGlobalModuleIndex,
693-
cas::ObjectStore &CAS, cas::ActionCache &Cache,
694+
cas::ObjectStore &CAS, cas::ActionCache &Cache, bool ignoreCAS,
694695
std::unique_ptr<llvm::MemoryBuffer> PCHBuffer) {
695696
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
696697

@@ -712,8 +713,9 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
712713
for (auto &Listener : DependencyCollectors)
713714
Listener->attachToASTReader(*Reader);
714715

715-
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
716-
CAS, Cache, ModuleCache, PP.getDiagnostics()));
716+
if (!ignoreCAS)
717+
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
718+
CAS, Cache, ModuleCache, PP.getDiagnostics()));
717719

718720
auto Listener = std::make_unique<ReadModuleNames>(PP);
719721
auto &ListenerRef = *Listener;
@@ -1901,9 +1903,10 @@ void CompilerInstance::createASTReader() {
19011903
for (auto &Listener : DependencyCollectors)
19021904
Listener->attachToASTReader(*TheASTReader);
19031905

1904-
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1905-
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1906-
getDiagnostics()));
1906+
if (!FEOpts.ModuleLoadIgnoreCAS)
1907+
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1908+
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1909+
getDiagnostics()));
19071910
}
19081911

19091912
bool CompilerInstance::loadModuleFile(StringRef FileName) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Tests for reusing a PCM output from CAS builds by a non-cas build.
2+
// This is to simulate a configuration by debugger without CAS support.
3+
4+
// REQUIRES: ondisk_cas
5+
6+
// RUN: rm -rf %t %t.cas
7+
// RUN: split-file %s %t
8+
9+
// RUN: llvm-cas --cas %t.cas --ingest %t > %t/casid
10+
11+
// == Build B
12+
13+
// RUN: %clang_cc1 -triple x86_64-apple-macos11 \
14+
// RUN: -fmodules -fmodule-name=B -fno-implicit-modules \
15+
// RUN: -emit-module %t/module.modulemap -o %t/B.pcm \
16+
// RUN: -fcas-path %t.cas -fcas-fs @%t/casid \
17+
// RUN: -fcache-compile-job -Rcompile-job-cache &> %t/B.out.txt
18+
// RUN: cat %t/B.out.txt | sed -E "s:^.*cache [a-z]+ for '([^']+)'.*$:\1:" > %t/B.key
19+
20+
// == Build A, importing B
21+
22+
// RUN: echo -n '-fmodule-file-cache-key %t/B.pcm ' > %t/B.import.rsp
23+
// RUN: cat %t/B.key >> %t/B.import.rsp
24+
25+
// RUN: %clang_cc1 -triple x86_64-apple-macos11 \
26+
// RUN: -fmodules -fmodule-name=A -fno-implicit-modules \
27+
// RUN: @%t/B.import.rsp -fmodule-file=%t/B.pcm \
28+
// RUN: -emit-module %t/module.modulemap -o %t/A.pcm \
29+
// RUN: -fcas-path %t.cas -fcas-fs @%t/casid \
30+
// RUN: -fcache-compile-job -Rcompile-job-cache &> %t/A.out.txt
31+
// RUN: cat %t/A.out.txt | sed -E "s:^.*cache [a-z]+ for '([^']+)'.*$:\1:" > %t/A.key
32+
33+
// == Build tu, importing A and B, without a CAS, this should fail.
34+
35+
// RUN: not %clang_cc1 -triple x86_64-apple-macos11 \
36+
// RUN: -fmodules -fno-implicit-modules \
37+
// RUN: -fmodule-file=%t/A.pcm\
38+
// RUN: -fmodule-file=%t/B.pcm\
39+
// RUN: -fsyntax-only %t/tu.c
40+
41+
// == Using option to ignore CAS info inside module
42+
43+
// RUN: %clang_cc1 -triple x86_64-apple-macos11 \
44+
// RUN: -fmodules -fno-implicit-modules \
45+
// RUN: -fmodule-file=%t/A.pcm\
46+
// RUN: -fmodule-file=%t/B.pcm\
47+
// RUN: -fsyntax-only %t/tu.c -fmodule-load-ignore-cas
48+
49+
//--- module.modulemap
50+
module A { header "A.h" export * }
51+
module B { header "B.h" }
52+
53+
//--- A.h
54+
#include "B.h"
55+
56+
//--- B.h
57+
void B(void);
58+
59+
//--- tu.c
60+
#include "A.h"
61+
void tu(void) {
62+
B();
63+
}

0 commit comments

Comments
 (0)