[clang] [clang] Extract in-memory module cache writes from `ASTWriter` (PR #190062)
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 1 23:10:40 PDT 2026
https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/190062
>From a3fe4d279f64f120e3b2df01a3d41f21e471035b Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 24 Mar 2026 12:54:22 -0700
Subject: [PATCH 1/2] [clang] Extract in-memory module cache writes from
`ASTWriter`
---
clang/include/clang/Basic/LangOptions.def | 1 -
clang/include/clang/Serialization/ASTWriter.h | 5 +--
clang/lib/Frontend/CompilerInstance.cpp | 12 ++++++
clang/lib/Frontend/FrontendActions.cpp | 7 +---
clang/lib/Serialization/ASTWriter.cpp | 8 +---
clang/lib/Serialization/GeneratePCH.cpp | 12 ++----
.../unittests/Frontend/FrontendActionTest.cpp | 38 -------------------
7 files changed, 20 insertions(+), 63 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index dd4c5a653d38b..6bba142aaf428 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -160,7 +160,6 @@ ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 3, CMK_None, Benign,
"compiling a module interface")
LANGOPT(CompilingPCH, 1, 0, Benign, "building a pch")
LANGOPT(BuildingPCHWithObjectFile, 1, 0, Benign, "building a pch which has a corresponding object file")
-LANGOPT(CacheGeneratedPCH, 1, 0, Benign, "cache generated PCH files in memory")
LANGOPT(PCHInstantiateTemplates, 1, 0, Benign, "instantiate templates while building a PCH")
LANGOPT(ModulesDeclUse , 1, 0, Compatible, "require declaration of module uses")
LANGOPT(ModulesSearchAll , 1, 1, Benign, "searching even non-imported modules to find unresolved references")
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index c69fa2b5b28a7..95ae8a6ba8c74 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -733,8 +733,7 @@ class ASTWriter : public ASTDeserializationListener,
/// the module but currently is merely a random 32-bit number.
ASTFileSignature WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
StringRef OutputFile, Module *WritingModule,
- StringRef isysroot,
- bool ShouldCacheASTInMemory = false);
+ StringRef isysroot);
/// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
@@ -1011,7 +1010,6 @@ class PCHGenerator : public SemaConsumer {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
bool AllowASTWithErrors;
- bool ShouldCacheASTInMemory;
protected:
ASTWriter &getWriter() { return Writer; }
@@ -1033,7 +1031,6 @@ class PCHGenerator : public SemaConsumer {
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
bool BuildingImplicitModule = false,
- bool ShouldCacheASTInMemory = false,
bool GeneratingReducedBMI = false);
~PCHGenerator() override;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index dbeafaea19ba4..a504cde306a35 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1488,6 +1488,18 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
ImportingInstance.getModuleCache().updateModuleTimestamp(ModuleFileName);
}
+ // This isn't strictly necessary, but it's more efficient to extract the AST
+ // file (which may be wrapped in an object file) now rather than doing so
+ // repeatedly in the readers.
+ const PCHContainerReader &Rdr = ImportingInstance.getPCHContainerReader();
+ StringRef ExtractedBuffer = Rdr.ExtractPCH(*Buffer);
+ // FIXME: Avoid the copy here by having InMemoryModuleCache accept both the
+ // owning buffer and the StringRef.
+ Buffer = llvm::MemoryBuffer::getMemBufferCopy(ExtractedBuffer);
+
+ ImportingInstance.getModuleCache().getInMemoryModuleCache().addBuiltPCM(
+ ModuleFileName, std::move(Buffer));
+
return true;
}
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 42f1ae3d83ed3..007393fa857e1 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -142,8 +142,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
CI.getCodeGenOpts(), FrontendOpts.ModuleFileExtensions,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
- FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule,
- +CI.getLangOpts().CacheGeneratedPCH));
+ FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
@@ -207,9 +206,7 @@ GenerateModuleAction::CreateMultiplexConsumer(CompilerInstance &CI,
/*IncludeTimestamps=*/
+CI.getFrontendOpts().BuildingImplicitModule &&
+CI.getFrontendOpts().IncludeTimestamps,
- /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule,
- /*ShouldCacheASTInMemory=*/
- +CI.getFrontendOpts().BuildingImplicitModule));
+ /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
return Consumers;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 20a01f86e95ac..4b3adce07f10c 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5496,7 +5496,7 @@ time_t ASTWriter::getTimestampForOutput(time_t ModTime) const {
ASTFileSignature
ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
StringRef OutputFile, Module *WritingModule,
- StringRef isysroot, bool ShouldCacheASTInMemory) {
+ StringRef isysroot) {
llvm::TimeTraceScope scope("WriteAST", OutputFile);
WritingAST = true;
@@ -5523,12 +5523,6 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
WritingAST = false;
- if (ShouldCacheASTInMemory) {
- // Construct MemoryBuffer and update buffer manager.
- ModCache.getInMemoryModuleCache().addBuiltPCM(
- OutputFile, llvm::MemoryBuffer::getMemBufferCopy(
- StringRef(Buffer.begin(), Buffer.size())));
- }
return Signature;
}
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index f8be0e45078db..7769d6170b845 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -28,14 +28,12 @@ PCHGenerator::PCHGenerator(
const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
- bool BuildingImplicitModule, bool ShouldCacheASTInMemory,
- bool GeneratingReducedBMI)
+ bool BuildingImplicitModule,bool GeneratingReducedBMI)
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
Writer(Stream, this->Buffer->Data, ModCache, CodeGenOpts, Extensions,
IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
- AllowASTWithErrors(AllowASTWithErrors),
- ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
+ AllowASTWithErrors(AllowASTWithErrors) {
this->Buffer->IsComplete = false;
}
@@ -84,8 +82,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
if (AllowASTWithErrors)
PP.getDiagnostics().getClient()->clear();
- Buffer->Signature = Writer.WriteAST(Subject, OutputFile, Module, isysroot,
- ShouldCacheASTInMemory);
+ Buffer->Signature = Writer.WriteAST(Subject, OutputFile, Module, isysroot);
Buffer->IsComplete = true;
}
@@ -111,8 +108,7 @@ CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,
std::make_shared<PCHBuffer>(), CodeGenOpts,
/*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
AllowASTWithErrors, /*IncludeTimestamps=*/false,
- /*BuildingImplicitModule=*/false, /*ShouldCacheASTInMemory=*/false,
- GeneratingReducedBMI) {}
+ /*BuildingImplicitModule=*/false, GeneratingReducedBMI) {}
Module *CXX20ModulesGenerator::getEmittingModule(ASTContext &Ctx) {
Module *M = Ctx.getCurrentNamedModule();
diff --git a/clang/unittests/Frontend/FrontendActionTest.cpp b/clang/unittests/Frontend/FrontendActionTest.cpp
index c4003182c4b1d..ae12b4ffcf931 100644
--- a/clang/unittests/Frontend/FrontendActionTest.cpp
+++ b/clang/unittests/Frontend/FrontendActionTest.cpp
@@ -259,42 +259,4 @@ TEST(ASTFrontendAction, ExternalSemaSource) {
EXPECT_EQ("This is a note", std::string(TDC->Note));
}
-TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
- // Create a temporary file for writing out the PCH that will be cleaned up.
- int PCHFD;
- llvm::SmallString<128> PCHFilename;
- ASSERT_FALSE(
- llvm::sys::fs::createTemporaryFile("test.h", "pch", PCHFD, PCHFilename));
- llvm::ToolOutputFile PCHFile(PCHFilename, PCHFD);
-
- for (bool ShouldCache : {false, true}) {
- auto Invocation = std::make_shared<CompilerInvocation>();
- Invocation->getLangOpts().CacheGeneratedPCH = ShouldCache;
- Invocation->getPreprocessorOpts().addRemappedFile(
- "test.h",
- MemoryBuffer::getMemBuffer("int foo(void) { return 1; }\n").release());
- Invocation->getFrontendOpts().Inputs.push_back(
- FrontendInputFile("test.h", Language::C));
- Invocation->getFrontendOpts().OutputFile = PCHFilename.str().str();
- Invocation->getFrontendOpts().ProgramAction = frontend::GeneratePCH;
- Invocation->getTargetOpts().Triple = "x86_64-apple-darwin19.0.0";
- CompilerInstance Compiler(std::move(Invocation));
- Compiler.setVirtualFileSystem(llvm::vfs::getRealFileSystem());
- Compiler.createDiagnostics();
-
- GeneratePCHAction TestAction;
- ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
-
- // Check whether the PCH was cached.
- if (ShouldCache)
- EXPECT_EQ(InMemoryModuleCache::Final,
- Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
- PCHFilename));
- else
- EXPECT_EQ(InMemoryModuleCache::Unknown,
- Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
- PCHFilename));
- }
-}
-
} // anonymous namespace
>From 3cafce85118236654dd2f7ca83fb768b49aa810b Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan at svoboda.ai>
Date: Wed, 1 Apr 2026 23:10:30 -0700
Subject: [PATCH 2/2] git-clang-format
---
clang/lib/Serialization/GeneratePCH.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index 7769d6170b845..8bc7e1782c2d9 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -28,7 +28,7 @@ PCHGenerator::PCHGenerator(
const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
- bool BuildingImplicitModule,bool GeneratingReducedBMI)
+ bool BuildingImplicitModule, bool GeneratingReducedBMI)
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
Writer(Stream, this->Buffer->Data, ModCache, CodeGenOpts, Extensions,
More information about the cfe-commits
mailing list