Skip to content

Commit 56c6a7a

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 0073bbe commit 56c6a7a

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
@@ -8488,6 +8488,11 @@ def fcas_input_file_id : Separate<["-"], "fcas-input-file-casid">,
84888488
Group<f_Group>, MetaVarName<"<ID>">,
84898489
MarshallingInfoString<FrontendOpts<"CASInputFileCASID">>;
84908490

8491+
defm module_load_ignore_cas : BoolFOption<"module-load-ignore-cas",
8492+
FrontendOpts<"ModuleLoadIgnoreCAS">, DefaultFalse,
8493+
PosFlag<SetTrue, [], [ClangOption], "Ignore CAS info when loading modules or PCHs">,
8494+
NegFlag<SetFalse>>;
8495+
84918496
// FIXME: Add to driver under -fexperimental-cache=compile-job.
84928497
defm cache_compile_job : BoolFOption<"cache-compile-job",
84938498
FrontendOpts<"CacheCompileJob">, DefaultFalse,

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ class CompilerInstance : public ModuleLoader {
800800
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
801801
void *DeserializationListener, bool OwnDeserializationListener,
802802
bool Preamble, bool UseGlobalModuleIndex,
803-
cas::ObjectStore &CAS, cas::ActionCache &Cache,
803+
cas::ObjectStore &CAS, cas::ActionCache &Cache, bool ignoreCAS,
804804
std::unique_ptr<llvm::MemoryBuffer> PCHBuffer = nullptr);
805805

806806
/// 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
@@ -558,6 +558,9 @@ class FrontendOptions {
558558
/// Use the blob in the CAS object as the input.
559559
std::string CASInputFileCASID;
560560

561+
/// If ignore all the CAS info from serialized AST like modules and PCHs.
562+
bool ModuleLoadIgnoreCAS = false;
563+
561564
/// When the input is a module map, the original module map file from which
562565
/// that map was inferred, if any (for umbrella modules).
563566
std::string OriginalModuleMap;

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,9 @@ void CompilerInstance::createPCHExternalASTSource(
669669
getASTContext(), getPCHContainerReader(),
670670
getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
671671
DeserializationListener, OwnDeserializationListener, Preamble,
672-
getFrontendOpts().UseGlobalModuleIndex,
673-
getOrCreateObjectStore(), getOrCreateActionCache(), std::move(PCHBuffer));
672+
getFrontendOpts().UseGlobalModuleIndex, getOrCreateObjectStore(),
673+
getOrCreateActionCache(), getFrontendOpts().ModuleLoadIgnoreCAS,
674+
std::move(PCHBuffer));
674675
}
675676

676677
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
@@ -683,7 +684,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
683684
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
684685
void *DeserializationListener, bool OwnDeserializationListener,
685686
bool Preamble, bool UseGlobalModuleIndex,
686-
cas::ObjectStore &CAS, cas::ActionCache &Cache,
687+
cas::ObjectStore &CAS, cas::ActionCache &Cache, bool ignoreCAS,
687688
std::unique_ptr<llvm::MemoryBuffer> PCHBuffer) {
688689
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
689690

@@ -705,8 +706,9 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
705706
for (auto &Listener : DependencyCollectors)
706707
Listener->attachToASTReader(*Reader);
707708

708-
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
709-
CAS, Cache, ModuleCache, PP.getDiagnostics()));
709+
if (!ignoreCAS)
710+
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
711+
CAS, Cache, ModuleCache, PP.getDiagnostics()));
710712

711713
auto Listener = std::make_unique<ReadModuleNames>(PP);
712714
auto &ListenerRef = *Listener;
@@ -1929,9 +1931,10 @@ void CompilerInstance::createASTReader() {
19291931
for (auto &Listener : DependencyCollectors)
19301932
Listener->attachToASTReader(*TheASTReader);
19311933

1932-
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1933-
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1934-
getDiagnostics()));
1934+
if (!FEOpts.ModuleLoadIgnoreCAS)
1935+
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1936+
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1937+
getDiagnostics()));
19351938
}
19361939

19371940
bool CompilerInstance::loadModuleFile(
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)