Skip to content

Commit fb595ac

Browse files
authored
[jit] Move out-of-process JIT cells from clang-20 to clang-22 (#924)
[ci] Move out-of-process JIT cells to llvm22. The OOP-JIT cells were pinned to clang-20 by patches/llvm/clang20-1-out-of-process.patch, which carried the clang::Interpreter::JITConfig surface CppInterOp depended on. Upstream release/22.x carries the equivalent surface as clang::IncrementalExecutorBuilder, so port lib/CppInterOp/Compatibility.h to it and bump both OOP cells (ubu24-x86 + osx26-arm) to clang-22 / python-3.14. The 966-line patch goes away; the cells line up with the rest of the matrix. Wire UpdateOrcRuntimePathCB into IncrementalCompilerBuilder so the orc_rt archive path is discovered from the driver's toolchain during CreateCpp() rather than hard-coded for x86_64 Linux; this also unblocks aarch64 Linux, so relax the CMakeLists OOP-JIT guard. Drop the public C-API pid_t GetExecutorPID() and its internal helper: upstream has no executor-PID accessor, the entry has no in-tree callers, and stubbing it to 0 would silently regress callers expecting a real PID. The upstream FDSimpleRemoteEPCTransport::sendMessage write(buf) uninit-bytes report persists in 22.x; replace etc/clang20-valgrind.supp with etc/clang22-valgrind.supp that anchors on the offending function and uses a "..." tail (the old supp pinned a libstdc++ .so version that no longer matches noble). Separately, clang-22 introduces an x86_64-only regression in many AST/Sema readers (clean on aarch64). Filed upstream as llvm/llvm-project#194147 with a one-line reproducer. The suppression file carries entries for the affected families: InitListExpr accessors, Sema::CheckForIntOverflow, SequenceChecker, Stmt::children, AnalyzeImplicitConversions, CFGBuilder::Visit, RecordExprEvaluator and AggExprEmitter init-list visits, InitListChecker::FillInEmpty*. Drop those entries when the upstream issue is resolved. On aarch64 / Ubuntu 24.04 against release/22.x: 349 tests (in-process + OOP-JIT variants), 320 PASSED, 29 SKIPPED. The OOP-JIT-vg cell on x86_64 reports 273 suppressions across 50 contexts and exits 0.
1 parent 306b4d3 commit fb595ac

10 files changed

Lines changed: 166 additions & 1057 deletions

File tree

.github/actions/Build_LLVM/action.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ runs:
3939
ninja LLVMOrcDebugging -j ${{ env.ncpus }}
4040
ninja clingInterpreter -j ${{ env.ncpus }}
4141
else
42-
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
43-
git apply -v ../patches/llvm/clang20-1-out-of-process.patch
44-
echo "Apply clang20-1-out-of-process.patch:"
45-
fi
4642
cd build
4743
cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects || 'clang' }}" \
4844
-DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build || 'host;NVPTX' }}" \

.github/workflows/main.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ jobs:
7777
# llvm_enable_projects: "clang"
7878
# llvm_targets_to_build: "host;NVPTX"
7979
# python-version: '3.14'
80-
# oop-jit stays on clang-20: patches/llvm/clang20-1-out-of-process.patch
81-
# only targets release/20.x; bump when a matching patch lands.
8280
include:
8381
# Ubuntu Arm
8482
- { name: ubu24-arm-gcc12-llvm22-vg, os: ubuntu-24.04-arm, compiler: gcc-12, clang-runtime: '22', Valgrind: On }
@@ -93,26 +91,24 @@ jobs:
9391
compiler: gcc-12
9492
clang-runtime: '22'
9593
coverage: true
96-
- name: ubu24-x86-gcc12-llvm20-oop-vg
94+
- name: ubu24-x86-gcc12-llvm22-oop-vg
9795
os: ubuntu-24.04
9896
compiler: gcc-12
99-
clang-runtime: '20'
97+
clang-runtime: '22'
10098
llvm_enable_projects: "clang;compiler-rt"
10199
oop-jit: On
102100
Valgrind: On
103-
python-version: '3.13'
104101
# MacOS Arm
105102
- { name: osx26-arm-clang-llvm22, os: macos-26, compiler: clang, clang-runtime: '22', llvm_targets_to_build: host }
106103
- { name: osx26-arm-clang-llvm21-cppyy, os: macos-26, compiler: clang, clang-runtime: '21', cppyy: On, llvm_targets_to_build: host }
107104
- { name: osx26-arm-clang-cling-llvm20-cppyy, os: macos-26, compiler: clang, clang-runtime: '20', cling: On, cppyy: On, root-llvm-tag: *root_llvm_tag }
108-
- name: osx26-arm-clang-llvm20-oop
105+
- name: osx26-arm-clang-llvm22-oop
109106
os: macos-26
110107
compiler: clang
111-
clang-runtime: '20'
108+
clang-runtime: '22'
112109
llvm_enable_projects: "clang;compiler-rt"
113110
llvm_targets_to_build: host
114111
oop-jit: On
115-
python-version: '3.13'
116112
# MacOS X86
117113
- { name: osx26-x86-clang-llvm21-cppyy, os: macos-26-intel, compiler: clang, clang-runtime: '21', cppyy: On, llvm_targets_to_build: host }
118114
- { name: osx26-x86-clang-cling-llvm20-cppyy, os: macos-26-intel, compiler: clang, clang-runtime: '20', cling: On, cppyy: On, root-llvm-tag: *root_llvm_tag }

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,10 @@ add_definitions(-DLLVM_BINARY_LIB_DIR="${LLVM_BINARY_LIB_DIR}")
344344

345345
if(LLVM_BUILT_WITH_OOP_JIT)
346346
if((CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") OR
347-
(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64"))
347+
(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|aarch64|arm64"))
348348
add_definitions(-DLLVM_BUILT_WITH_OOP_JIT)
349349
else()
350-
message(FATAL_ERROR "LLVM_BUILT_WITH_OOP_JIT is only supported on MacOS arm64 or Linux x86_64. Build aborted.")
350+
message(FATAL_ERROR "LLVM_BUILT_WITH_OOP_JIT is only supported on MacOS arm64 or Linux (x86_64/aarch64). Build aborted.")
351351
endif()
352352
endif()
353353

etc/clang20-valgrind.supp

Lines changed: 0 additions & 18 deletions
This file was deleted.

etc/clang22-valgrind.supp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Upstream LLVM write(buf) uninit-bytes via the EPC transport, still
2+
# present in release/22.x. No llvm/llvm-project issue filed yet; if you
3+
# touch this file, please file one and add a reference here.
4+
{
5+
Clang 22 Out of Process: uninitialised bytes in FDSimpleRemoteEPCTransport::sendMessage
6+
Memcheck:Param
7+
write(buf)
8+
fun:__libc_write
9+
fun:write
10+
fun:_ZN4llvm3orc26FDSimpleRemoteEPCTransport11sendMessageENS0_21SimpleRemoteEPCOpcodeEmNS0_12ExecutorAddrENS_8ArrayRefIcEE
11+
...
12+
}
13+
14+
# llvm/llvm-project#194147: clang-22 on x86_64 reads uninitialised bytes
15+
# in many AST/Sema paths (regression vs clang-20). Architecture-dependent
16+
# (clean on aarch64). Drop this whole block once the upstream issue lands.
17+
18+
{
19+
llvm/llvm-project#194147: InitListExpr::isTransparent
20+
Memcheck:Cond
21+
fun:_ZNK5clang12InitListExpr13isTransparentEv
22+
...
23+
}
24+
{
25+
llvm/llvm-project#194147: InitListExpr::getInit
26+
Memcheck:Cond
27+
fun:_ZN5clang12InitListExpr7getInitEj
28+
...
29+
}
30+
{
31+
llvm/llvm-project#194147: InitListExpr::getInit const
32+
Memcheck:Cond
33+
fun:_ZNK5clang12InitListExpr7getInitEj
34+
...
35+
}
36+
{
37+
llvm/llvm-project#194147: InitListExpr::setInit
38+
Memcheck:Cond
39+
fun:_ZN5clang12InitListExpr7setInitEjPNS_4ExprE
40+
...
41+
}
42+
{
43+
llvm/llvm-project#194147: InitListExpr::resizeInits
44+
Memcheck:Cond
45+
fun:_ZN5clang12InitListExpr11resizeInitsERKNS_10ASTContextEj
46+
...
47+
}
48+
{
49+
llvm/llvm-project#194147: InitListExpr::resizeInits via memset
50+
Memcheck:Cond
51+
fun:memset
52+
fun:_ZN5clang12InitListExpr11resizeInitsERKNS_10ASTContextEj
53+
...
54+
}
55+
56+
{
57+
llvm/llvm-project#194147: Sema::CheckForIntOverflow Cond
58+
Memcheck:Cond
59+
fun:_ZN5clang4Sema19CheckForIntOverflowEPKNS_4ExprE
60+
...
61+
}
62+
{
63+
llvm/llvm-project#194147: Sema::CheckForIntOverflow Value8
64+
Memcheck:Value8
65+
fun:_ZN5clang4Sema19CheckForIntOverflowEPKNS_4ExprE
66+
...
67+
}
68+
{
69+
llvm/llvm-project#194147: SequenceChecker::SequenceExpressionsInOrder
70+
Memcheck:Cond
71+
fun:*SequenceChecker*SequenceExpressionsInOrder*
72+
...
73+
}
74+
75+
{
76+
llvm/llvm-project#194147: Stmt::children via AnalyzeImplicitConversions
77+
Memcheck:Cond
78+
fun:_ZN5clang4Stmt8childrenEv
79+
fun:*AnalyzeImplicitConversions*
80+
...
81+
}
82+
{
83+
llvm/llvm-project#194147: AnalyzeImplicitConversions leaf
84+
Memcheck:Cond
85+
fun:*AnalyzeImplicitConversions*
86+
...
87+
}
88+
{
89+
llvm/llvm-project#194147: CFGBuilder::Visit Cond
90+
Memcheck:Cond
91+
fun:*CFGBuilder*Visit*
92+
...
93+
}
94+
{
95+
llvm/llvm-project#194147: CFGBuilder::Visit Value8
96+
Memcheck:Value8
97+
fun:*CFGBuilder*Visit*
98+
...
99+
}
100+
101+
{
102+
llvm/llvm-project#194147: RecordExprEvaluator::VisitCXXParenListOrInitListExpr
103+
Memcheck:Cond
104+
fun:*RecordExprEvaluator*VisitCXXParenListOrInitListExpr*
105+
...
106+
}
107+
{
108+
llvm/llvm-project#194147: AggExprEmitter init-list visits
109+
Memcheck:Cond
110+
fun:*AggExprEmitter*Visit*InitListExpr*
111+
...
112+
}
113+
114+
{
115+
llvm/llvm-project#194147: InitListChecker::FillInEmptyInitForField
116+
Memcheck:Cond
117+
fun:*InitListChecker*FillInEmptyInitForField*
118+
...
119+
}
120+
{
121+
llvm/llvm-project#194147: InitListChecker::FillInEmptyInitializations
122+
Memcheck:Cond
123+
fun:*InitListChecker*FillInEmptyInitializations*
124+
...
125+
}

include/CppInterOp/CppInterOp.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,12 @@
2020

2121
#include "CppInterOp/CppInterOpTypes.h"
2222

23-
#include <sys/types.h>
24-
2523
namespace CppImpl {
2624

2725
// Public API function declarations. Generated by cppinterop-tblgen
2826
// from CppInterOp.td. Do not edit this section by hand.
2927
#include "CppInterOp/CppInterOpDecl.inc"
3028

31-
#ifndef _WIN32
32-
/// Returns the process ID of the executor process.
33-
/// \returns the PID of the executor process.
34-
CPPINTEROP_API pid_t GetExecutorPID();
35-
#endif
36-
3729
} // namespace CppImpl
3830

3931
// NOLINTNEXTLINE(misc-unused-alias-decls)

lib/CppInterOp/Compatibility.h

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ inline void codeComplete(std::vector<std::string>& Results,
237237

238238
#ifdef LLVM_BUILT_WITH_OOP_JIT
239239
#include "clang/Basic/Version.h"
240+
#include "clang/Interpreter/IncrementalExecutor.h"
240241

241242
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
242243

@@ -392,6 +393,29 @@ createClangInterpreter(std::vector<const char*>& args, int stdin_fd = -1,
392393
clang::IncrementalCompilerBuilder CB;
393394
CB.SetCompilerArgs(CompilerArgs);
394395

396+
bool outOfProcess;
397+
#if defined(_WIN32) || !defined(LLVM_BUILT_WITH_OOP_JIT)
398+
outOfProcess = false;
399+
#else
400+
outOfProcess = std::any_of(args.begin(), args.end(), [](const char* arg) {
401+
return llvm::StringRef(arg).trim() == "--use-oop-jit";
402+
});
403+
#endif
404+
405+
#ifdef LLVM_BUILT_WITH_OOP_JIT
406+
// Why: UpdateOrcRuntimePathCB is the upstream hook that discovers the
407+
// orc_rt location from the driver's toolchain during CreateCpp() /
408+
// CreateCudaHost(); it only fires when IsOutOfProcess is already true,
409+
// so the flag and the callback must be set before the CompilerInstance
410+
// is built.
411+
auto OutOfProcessConfig =
412+
std::make_unique<clang::IncrementalExecutorBuilder>();
413+
if (outOfProcess) {
414+
OutOfProcessConfig->IsOutOfProcess = true;
415+
CB.SetDriverCompilationCallback(OutOfProcessConfig->UpdateOrcRuntimePathCB);
416+
}
417+
#endif
418+
395419
std::unique_ptr<clang::CompilerInstance> DeviceCI;
396420
if (CudaEnabled) {
397421
if (OffloadArch.empty())
@@ -421,48 +445,29 @@ createClangInterpreter(std::vector<const char*>& args, int stdin_fd = -1,
421445
if (CudaEnabled)
422446
DeviceCI->LoadRequestedPlugins();
423447

424-
bool outOfProcess;
425-
#if defined(_WIN32) || !defined(LLVM_BUILT_WITH_OOP_JIT)
426-
outOfProcess = false;
427-
#else
428-
outOfProcess = std::any_of(args.begin(), args.end(), [](const char* arg) {
429-
return llvm::StringRef(arg).trim() == "--use-oop-jit";
430-
});
431-
#endif
432-
433448
#ifdef LLVM_BUILT_WITH_OOP_JIT
434-
435-
clang::Interpreter::JITConfig OutOfProcessConfig;
436449
if (outOfProcess) {
437-
OutOfProcessConfig.IsOutOfProcess = true;
438-
OutOfProcessConfig.OOPExecutor =
450+
OutOfProcessConfig->OOPExecutor =
439451
LLVM_BINARY_LIB_DIR "/bin/llvm-jitlink-executor";
440-
OutOfProcessConfig.UseSharedMemory = false;
441-
OutOfProcessConfig.SlabAllocateSize = 0;
442-
OutOfProcessConfig.CustomizeFork = [stdin_fd, stdout_fd,
443-
stderr_fd]() { // Lambda defined inline
452+
OutOfProcessConfig->UseSharedMemory = false;
453+
OutOfProcessConfig->SlabAllocateSize = 0;
454+
OutOfProcessConfig->CustomizeFork = [stdin_fd, stdout_fd,
455+
stderr_fd]() { // Lambda defined inline
444456
dup2(stdin_fd, STDIN_FILENO);
445457
dup2(stdout_fd, STDOUT_FILENO);
446458
dup2(stderr_fd, STDERR_FILENO);
447459

448460
setvbuf(fdopen(stdout_fd, "w+"), nullptr, _IONBF, 0);
449461
setvbuf(fdopen(stderr_fd, "w+"), nullptr, _IONBF, 0);
450462
};
451-
452-
#ifdef __APPLE__
453-
std::string OrcRuntimePath = LLVM_BINARY_LIB_DIR "/lib/clang/" STRINGIFY(
454-
LLVM_VERSION_MAJOR) "/lib/darwin/liborc_rt_osx.a";
455-
#else
456-
std::string OrcRuntimePath = LLVM_BINARY_LIB_DIR "/lib/clang/" STRINGIFY(
457-
LLVM_VERSION_MAJOR) "/lib/x86_64-unknown-linux-gnu/liborc_rt.a";
458-
#endif
459-
OutOfProcessConfig.OrcRuntimePath = OrcRuntimePath;
463+
// OrcRuntimePath was populated by UpdateOrcRuntimePathCB above.
460464
}
461465
auto innerOrErr =
462-
CudaEnabled
463-
? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
464-
std::move(DeviceCI))
465-
: clang::Interpreter::create(std::move(*ciOrErr), OutOfProcessConfig);
466+
CudaEnabled ? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
467+
std::move(DeviceCI))
468+
: clang::Interpreter::create(
469+
std::move(*ciOrErr),
470+
outOfProcess ? std::move(OutOfProcessConfig) : nullptr);
466471
#else
467472
if (outOfProcess) {
468473
llvm::errs()

lib/CppInterOp/CppInterOp.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4833,16 +4833,4 @@ int Undo(unsigned N) {
48334833
#endif
48344834
}
48354835

4836-
#ifndef _WIN32
4837-
pid_t GetExecutorPID() {
4838-
INTEROP_TRACE();
4839-
#ifdef LLVM_BUILT_WITH_OOP_JIT
4840-
auto& I = getInterp();
4841-
return INTEROP_RETURN(I.getOutOfProcessExecutorPID());
4842-
#endif
4843-
return INTEROP_RETURN(getpid());
4844-
}
4845-
4846-
#endif
4847-
48484836
} // namespace CppImpl

lib/CppInterOp/CppInterOpInterpreter.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,6 @@ class Interpreter {
335335
return llvm::orc::ExecutorAddr(*AddrOrErr);
336336
}
337337

338-
#ifndef _WIN32
339-
[[nodiscard]] pid_t getOutOfProcessExecutorPID() const {
340-
#ifdef LLVM_BUILT_WITH_OOP_JIT
341-
return inner->getOutOfProcessExecutorPID();
342-
#endif
343-
return 0;
344-
}
345-
#endif
346-
347338
/// \returns the \c ExecutorAddr of a given name as written in the object
348339
/// file.
349340
llvm::Expected<llvm::orc::ExecutorAddr>

0 commit comments

Comments
 (0)