[clang] Allow for custom code model in clang::Interpreter (PR #156977)
Jeaye Wilkerson via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 7 13:54:48 PDT 2025
https://github.com/jeaye updated https://github.com/llvm/llvm-project/pull/156977
>From 65d55e32ffa78138c016040c1344e929528a017b Mon Sep 17 00:00:00 2001
From: jeaye <contact at jeaye.com>
Date: Thu, 4 Sep 2025 13:48:40 -0700
Subject: [PATCH 1/2] Allow for custom code model in clang::Interpreter
This is necessary when using ASan, since the larger code size will lead
to errors such as:
```
JIT session error: In graph clojure_core-clojure.core$clojure_core_cpp_cast_24538-24543-jitted-objectbuffer, section .eh_frame: relocation target 0x7bffe374b000 (DW.ref.__gxx_personality_v0) is out of range of Delta32 fixup at address 0x7bffe374b000 (<anonymous block> @ 0x7fffebf48158 + 0x13)
```
Previously, `clang::Interpreter` would hard-code the usage of a small
code model. With this change, we default to small, but allow for custom
values. This related to #102858 and #135401.
There is no change to default behavior here.
---
clang/include/clang/Interpreter/Interpreter.h | 9 +++++++--
clang/lib/Interpreter/Interpreter.cpp | 12 ++++++++----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h
index 8c124aadf1005..3890a06917f76 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -115,11 +115,15 @@ class Interpreter {
/// An optional compiler instance for CUDA offloading
std::unique_ptr<CompilerInstance> DeviceCI;
+ /// An optional code model to provide to the JITTargetMachineBuilder
+ std::optional<llvm::CodeModel::Model> CM;
+
protected:
// Derived classes can use an extended interface of the Interpreter.
Interpreter(std::unique_ptr<CompilerInstance> Instance, llvm::Error &Err,
std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr,
- std::unique_ptr<clang::ASTConsumer> Consumer = nullptr);
+ std::unique_ptr<clang::ASTConsumer> Consumer = nullptr,
+ const std::optional<llvm::CodeModel::Model> &CM = std::nullopt);
// Create the internal IncrementalExecutor, or re-create it after calling
// ResetExecutor().
@@ -133,7 +137,8 @@ class Interpreter {
virtual ~Interpreter();
static llvm::Expected<std::unique_ptr<Interpreter>>
create(std::unique_ptr<CompilerInstance> CI,
- std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr);
+ std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr,
+ const std::optional<llvm::CodeModel::Model> &CM = std::nullopt);
static llvm::Expected<std::unique_ptr<Interpreter>>
createWithCUDA(std::unique_ptr<CompilerInstance> CI,
std::unique_ptr<CompilerInstance> DCI);
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 47995216fac46..a483506932107 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -251,8 +251,9 @@ IncrementalCompilerBuilder::CreateCudaHost() {
Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
llvm::Error &ErrOut,
std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder,
- std::unique_ptr<clang::ASTConsumer> Consumer)
- : JITBuilder(std::move(JITBuilder)) {
+ std::unique_ptr<clang::ASTConsumer> Consumer,
+ const std::optional<llvm::CodeModel::Model> &CM)
+ : CM(CM), JITBuilder(std::move(JITBuilder)) {
CI = std::move(Instance);
llvm::ErrorAsOutParameter EAO(&ErrOut);
auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
@@ -349,10 +350,11 @@ const char *const Runtimes = R"(
llvm::Expected<std::unique_ptr<Interpreter>>
Interpreter::create(std::unique_ptr<CompilerInstance> CI,
- std::unique_ptr<llvm::orc::LLJITBuilder> JB) {
+ std::unique_ptr<llvm::orc::LLJITBuilder> JB,
+ const std::optional<llvm::CodeModel::Model> &CM) {
llvm::Error Err = llvm::Error::success();
auto Interp = std::unique_ptr<Interpreter>(
- new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr));
+ new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr, nullptr, CM));
if (Err)
return std::move(Err);
@@ -526,6 +528,8 @@ llvm::Error Interpreter::CreateExecutor() {
auto JTMB = createJITTargetMachineBuilder(TT);
if (!JTMB)
return JTMB.takeError();
+ if (CM)
+ JTMB->setCodeModel(CM);
auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
if (!JB)
return JB.takeError();
>From 034de77ee1c13dbeb8bcacd7189dcbdb3335fd04 Mon Sep 17 00:00:00 2001
From: jeaye <contact at jeaye.com>
Date: Sun, 7 Sep 2025 13:53:51 -0700
Subject: [PATCH 2/2] Port to use the new JitConfig
---
clang/include/clang/Interpreter/Interpreter.h | 7 ++-----
clang/lib/Interpreter/Interpreter.cpp | 4 ++--
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h
index a7be8041e47e1..fcc270a17001e 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -120,9 +120,6 @@ class Interpreter {
/// An optional compiler instance for CUDA offloading
std::unique_ptr<CompilerInstance> DeviceCI;
- /// An optional code model to provide to the JITTargetMachineBuilder
- std::optional<llvm::CodeModel::Model> CM;
-
public:
struct JITConfig {
/// Indicates whether out-of-process JIT execution is enabled.
@@ -139,12 +136,12 @@ class Interpreter {
/// PID of the out-of-process JIT executor.
uint32_t ExecutorPID = 0;
/// An optional code model to provide to the JITTargetMachineBuilder
- std::optional<llvm::CodeModel::Model> CM;
+ std::optional<llvm::CodeModel::Model> CM = std::nullopt;
JITConfig()
: IsOutOfProcess(false), OOPExecutor(""), OOPExecutorConnect(""),
UseSharedMemory(false), SlabAllocateSize(0), OrcRuntimePath(""),
- ExecutorPID(0) {}
+ ExecutorPID(0), CM(std::nullopt) {}
};
protected:
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 457d03f962be5..84f1c363b5f6f 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -647,8 +647,8 @@ llvm::Error Interpreter::CreateExecutor(JITConfig Config) {
auto JTMB = createJITTargetMachineBuilder(TT);
if (!JTMB)
return JTMB.takeError();
- if (CM)
- JTMB->setCodeModel(CM);
+ if (Config.CM)
+ JTMB->setCodeModel(Config.CM);
auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
if (!JB)
return JB.takeError();
More information about the cfe-commits
mailing list