Skip to content

Commit c2f3689

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 bffad72 commit c2f3689

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
@@ -8386,6 +8386,11 @@ def fcas_include_tree : Separate<["-"], "fcas-include-tree">,
83868386
HelpText<"Configure the frontend to use a CAS include tree.">,
83878387
MarshallingInfoString<FrontendOpts<"CASIncludeTreeID">>;
83888388

8389+
defm module_load_ignore_cas : BoolFOption<"module-load-ignore-cas",
8390+
FrontendOpts<"ModuleLoadIgnoreCAS">, DefaultFalse,
8391+
PosFlag<SetTrue, [], [ClangOption], "Ignore CAS info when loading modules or PCHs">,
8392+
NegFlag<SetFalse>>;
8393+
83898394
// FIXME: Add to driver under -fexperimental-cache=compile-job.
83908395
defm cache_compile_job : BoolFOption<"cache-compile-job",
83918396
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
@@ -552,6 +552,9 @@ class FrontendOptions {
552552
/// Use the provided CAS include tree.
553553
std::string CASIncludeTreeID;
554554

555+
/// If ignore all the CAS info from serialized AST like modules and PCHs.
556+
bool ModuleLoadIgnoreCAS = false;
557+
555558
/// When the input is a module map, the original module map file from which
556559
/// that map was inferred, if any (for umbrella modules).
557560
std::string OriginalModuleMap;

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,9 @@ void CompilerInstance::createPCHExternalASTSource(
666666
getASTContext(), getPCHContainerReader(),
667667
getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
668668
DeserializationListener, OwnDeserializationListener, Preamble,
669-
getFrontendOpts().UseGlobalModuleIndex,
670-
getOrCreateObjectStore(), getOrCreateActionCache(), std::move(PCHBuffer));
669+
getFrontendOpts().UseGlobalModuleIndex, getOrCreateObjectStore(),
670+
getOrCreateActionCache(), getFrontendOpts().ModuleLoadIgnoreCAS,
671+
std::move(PCHBuffer));
671672
}
672673

673674
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
@@ -680,7 +681,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
680681
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
681682
void *DeserializationListener, bool OwnDeserializationListener,
682683
bool Preamble, bool UseGlobalModuleIndex,
683-
cas::ObjectStore &CAS, cas::ActionCache &Cache,
684+
cas::ObjectStore &CAS, cas::ActionCache &Cache, bool ignoreCAS,
684685
std::unique_ptr<llvm::MemoryBuffer> PCHBuffer) {
685686
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
686687

@@ -702,8 +703,9 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
702703
for (auto &Listener : DependencyCollectors)
703704
Listener->attachToASTReader(*Reader);
704705

705-
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
706-
CAS, Cache, ModuleCache, PP.getDiagnostics()));
706+
if (!ignoreCAS)
707+
Reader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
708+
CAS, Cache, ModuleCache, PP.getDiagnostics()));
707709

708710
auto Listener = std::make_unique<ReadModuleNames>(PP);
709711
auto &ListenerRef = *Listener;
@@ -1897,9 +1899,10 @@ void CompilerInstance::createASTReader() {
18971899
for (auto &Listener : DependencyCollectors)
18981900
Listener->attachToASTReader(*TheASTReader);
18991901

1900-
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1901-
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1902-
getDiagnostics()));
1902+
if (!FEOpts.ModuleLoadIgnoreCAS)
1903+
TheASTReader->addListener(std::make_unique<CompileCacheASTReaderHelper>(
1904+
getOrCreateObjectStore(), getOrCreateActionCache(), getModuleCache(),
1905+
getDiagnostics()));
19031906
}
19041907

19051908
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)