Skip to content

Commit 5760b41

Browse files
author
kr-2003
committed
Out-Of-Process on CppInterOp
1 parent 0b1271a commit 5760b41

24 files changed

+1553
-99
lines changed

.github/actions/Build_LLVM/action.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ runs:
4343
ninja LLVMOrcDebugging -j ${{ env.ncpus }}
4444
ninja clingInterpreter -j ${{ env.ncpus }}
4545
else
46+
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
47+
git apply -v ../patches/llvm/clang20-2-out-of-process.patch
48+
echo "Apply clang20-2-out-of-process.patch:"
49+
fi
4650
cd build
4751
cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects}}" \
4852
-DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" \
@@ -58,6 +62,14 @@ runs:
5862
-DLLVM_INCLUDE_TESTS=OFF \
5963
../llvm
6064
ninja clang clangInterpreter clangStaticAnalyzerCore -j ${{ env.ncpus }}
65+
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
66+
if [[ "${{ matrix.os }}" == macos* ]]; then
67+
SUFFIX="_osx"
68+
elif [[ "${{ matrix.os }}" == ubuntu* ]]; then
69+
SUFFIX="-x86_64"
70+
fi
71+
ninja clang-repl llvm-jitlink-executor orc_rt${SUFFIX} -j ${{ env.ncpus }}
72+
fi
6173
cd ./tools/
6274
rm -rf $(find . -maxdepth 1 ! -name "clang" ! -name ".")
6375
cd ..

.github/actions/Build_and_Test_CppInterOp/action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ runs:
4848
-DCODE_COVERAGE=${{ env.CODE_COVERAGE }} \
4949
-DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR \
5050
-DLLVM_ENABLE_WERROR=On \
51+
-DLLVM_BUILT_WITH_OOP_JIT=${{ matrix.oop-jit }} \
5152
../
5253
fi
5354
docs_on=$(echo "${{ matrix.documentation }}" | tr '[:lower:]' '[:upper:]')
@@ -60,6 +61,8 @@ runs:
6061
if [[ "${os}" != "macos"* ]]; then
6162
valgrind --show-error-list=yes --track-origins=yes --error-exitcode=1 unittests/CppInterOp/CppInterOpTests/unittests/bin/${{ env.BUILD_TYPE }}/CppInterOpTests
6263
fi
64+
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
65+
./unittests/CppInterOp/CppInterOpTests/unittests/bin/${{ env.BUILD_TYPE }}/CppInterOpTests --use-oop-jit
6366
fi
6467
echo "CB_PYTHON_DIR=$CB_PYTHON_DIR" >> $GITHUB_ENV
6568
echo "CPPINTEROP_BUILD_DIR=$CPPINTEROP_BUILD_DIR" >> $GITHUB_ENV

.github/workflows/main.yml

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,6 @@ jobs:
2323
matrix:
2424
include:
2525
# Ubuntu Arm Jobs
26-
- name: ubu22-arm-gcc12-clang-repl-20-coverage
27-
os: ubuntu-22.04-arm
28-
compiler: gcc-12
29-
clang-runtime: '20'
30-
cling: Off
31-
cppyy: Off
32-
llvm_enable_projects: "clang"
33-
llvm_targets_to_build: "host;NVPTX"
34-
coverage: true
3526
- name: ubu24-arm-gcc12-clang-repl-20
3627
os: ubuntu-24.04-arm
3728
compiler: gcc-12
@@ -66,6 +57,16 @@ jobs:
6657
llvm_enable_projects: "clang"
6758
llvm_targets_to_build: "host;NVPTX"
6859
# Ubuntu X86 Jobs
60+
- name: ubu22-x86-gcc12-clang-repl-20-coverage
61+
os: ubuntu-22.04
62+
compiler: gcc-12
63+
clang-runtime: '20'
64+
cling: Off
65+
cppyy: Off
66+
llvm_enable_projects: "clang;compiler-rt"
67+
llvm_targets_to_build: "host;NVPTX"
68+
coverage: true
69+
oop-jit: On
6970
- name: ubu24-x86-gcc12-clang-repl-20
7071
os: ubuntu-24.04
7172
compiler: gcc-12
@@ -74,6 +75,15 @@ jobs:
7475
cppyy: Off
7576
llvm_enable_projects: "clang"
7677
llvm_targets_to_build: "host;NVPTX"
78+
- name: ubu24-x86-gcc12-clang-repl-20-out-of-process
79+
os: ubuntu-24.04
80+
compiler: gcc-12
81+
clang-runtime: '20'
82+
cling: Off
83+
cppyy: Off
84+
llvm_enable_projects: "clang;compiler-rt"
85+
llvm_targets_to_build: "host;NVPTX"
86+
oop-jit: On
7787
- name: ubu24-x86-gcc12-clang-repl-19-cppyy
7888
os: ubuntu-24.04
7989
compiler: gcc-12
@@ -100,6 +110,15 @@ jobs:
100110
llvm_enable_projects: "clang"
101111
llvm_targets_to_build: "host;NVPTX"
102112
# MacOS Arm Jobs
113+
- name: osx15-arm-clang-clang-repl-20-out-of-process
114+
os: macos-15
115+
compiler: clang
116+
clang-runtime: '20'
117+
cling: Off
118+
cppyy: Off
119+
llvm_enable_projects: "clang;compiler-rt"
120+
llvm_targets_to_build: "host"
121+
oop-jit: On
103122
- name: osx15-arm-clang-clang-repl-20
104123
os: macos-15
105124
compiler: clang
@@ -220,7 +239,7 @@ jobs:
220239
path: |
221240
llvm-project
222241
${{ matrix.cling=='On' && 'cling' || '' }}
223-
key: ${{ env.CLING_HASH }}-${{ runner.os }}-${{ matrix.os }}-${{ matrix.compiler }}-clang-${{ matrix.clang-runtime }}.x-patch-${{ hashFiles(format('patches/llvm/clang{0}-*.patch', matrix.clang-runtime)) || 'none' }}
242+
key: ${{ env.CLING_HASH }}-${{ runner.os }}-${{ matrix.os }}-${{ matrix.compiler }}-clang-${{ matrix.clang-runtime }}.x-patch-${{ hashFiles(format('patches/llvm/clang{0}-*.patch', matrix.clang-runtime)) || 'none' }}${{ matrix.oop-jit == 'On' && '-oop' || '' }}
224243

225244
- name: Setup default Build Type
226245
uses: ./.github/actions/Miscellaneous/Select_Default_Build_Type

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,18 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
298298
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
299299
add_definitions(${LLVM_DEFINITIONS_LIST})
300300

301+
string(REGEX REPLACE "/build/lib/cmake/llvm$" "" LLVM_SOURCE_DIR "${LLVM_DIR}")
302+
add_definitions(-DLLVM_SOURCE_DIR="${LLVM_SOURCE_DIR}")
303+
304+
if(LLVM_BUILT_WITH_OOP_JIT)
305+
if((CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") OR
306+
(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64"))
307+
add_definitions(-DLLVM_BUILT_WITH_OOP_JIT)
308+
else()
309+
message(FATAL_ERROR "LLVM_BUILT_WITH_OOP_JIT is only supported on Darwin arm64 or Linux x86_64. Build aborted.")
310+
endif()
311+
endif()
312+
301313
# If the llvm sources are present add them with higher priority.
302314
if (LLVM_BUILD_MAIN_SRC_DIR)
303315
# LLVM_INCLUDE_DIRS contains the include paths to both LLVM's source and

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ git clone --depth=1 --branch release/20.x https://github.com/llvm/llvm-project.g
111111
cd llvm-project
112112
```
113113

114+
If you want to have out-of-process JIT execution enabled in CppInterOp, then apply this patch on Linux and MacOS environment.
115+
> Note that this patch will not work for Windows because out-of-process JIT execution is currently implemented for Linux and MacOS only.
116+
117+
```bash
118+
git apply -v ../CppInterOp/patches/llvm/clang20-2-out-of-process.patch
119+
```
120+
114121
##### Build Clang-REPL
115122

116123
Clang-REPL is an interpreter that CppInterOp works alongside. Build Clang (and
@@ -202,6 +209,33 @@ and clone cppyy-backend repository where we will be installing the CppInterOp li
202209
git clone --depth=1 https://github.com/compiler-research/cppyy-backend.git
203210
```
204211

212+
##### Build Clang-REPL with Out-of-Process JIT Execution
213+
214+
To have ``Out-of-Process JIT Execution`` enabled, run following commands to build clang and clang-repl to support this feature:
215+
> Only for Linux x86_64 and Macos amr64
216+
```bash
217+
mkdir build
218+
cd build
219+
cmake -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" \
220+
-DLLVM_TARGETS_TO_BUILD="host;NVPTX" \
221+
-DCMAKE_BUILD_TYPE=Release \
222+
-DLLVM_ENABLE_ASSERTIONS=ON \
223+
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
224+
-DCLANG_ENABLE_ARCMT=OFF \
225+
-DCLANG_ENABLE_FORMAT=OFF \
226+
-DCLANG_ENABLE_BOOTSTRAP=OFF \
227+
../llvm
228+
```
229+
230+
## For Linux x86_64
231+
```bash
232+
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt-x86_64 --parallel $(nproc --all)
233+
```
234+
## For MacOS arm64
235+
```bash
236+
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt_osx --parallel $(sysctl -n hw.ncpu)
237+
```
238+
205239
#### Build Cling and related dependencies
206240

207241
The Cling interpreter and depends on its own customised version of `llvm-project`,
@@ -265,6 +299,34 @@ Now CppInterOp can be built. This can be done by executing
265299
```bash
266300
mkdir CppInterOp/build/
267301
cd CppInterOp/build/
302+
```
303+
304+
On Windows execute
305+
306+
```powershell
307+
mkdir CppInterOp\build\
308+
cd CppInterOp\build\
309+
```
310+
311+
Now if you want to build CppInterOp with Clang-REPL then execute the following commands on Linux and MacOS
312+
313+
```bash
314+
cmake -DBUILD_SHARED_LIBS=ON -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR ..
315+
cmake --build . --target install --parallel $(nproc --all)
316+
```
317+
318+
and
319+
320+
> Do make sure to pass ``DLLVM_BUILT_WITH_OOP_JIT=ON``, if you want to have out-of-process JIT execution feature enabled.
321+
322+
```powershell
323+
cmake -DLLVM_DIR=$env:LLVM_DIR\build\lib\cmake\llvm -DClang_DIR=$env:LLVM_DIR\build\lib\cmake\clang -DCMAKE_INSTALL_PREFIX=$env:CPPINTEROP_DIR ..
324+
cmake --build . --target install --parallel $env:ncpus
325+
```
326+
327+
on Windows. If alternatively you would like to install CppInterOp with Cling then execute the following commands on Linux and MacOS.
328+
329+
```bash
268330
cmake -DBUILD_SHARED_LIBS=ON -DCPPINTEROP_USE_CLING=ON -DCPPINTEROP_USE_REPL=Off -DCling_DIR=$LLVM_DIR/build/tools/cling -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR ..
269331
cmake --build . --target install --parallel $(nproc --all)
270332
```

docs/InstallationAndUsage.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ Clone the 20.x release of the LLVM project repository.
4141
git clone --depth=1 --branch release/20.x https://github.com/llvm/llvm-project.git
4242
cd llvm-project
4343
44+
If you want to have out-of-process JIT execution enabled in CppInterOp, then apply this patch on Linux and MacOS environment.
45+
.. note::
46+
47+
This patch will not work for Windows because out-of-process JIT execution is currently implemented for Linux and MacOS only.
48+
49+
.. code:: bash
50+
51+
git apply -v ../CppInterOp/patches/llvm/clang20-2-out-of-process.patch
52+
4453
******************
4554
Build Clang-REPL
4655
******************
@@ -99,6 +108,34 @@ On Windows you execute the following
99108
$env:LLVM_DIR= $PWD.Path
100109
cd ..\
101110
111+
***************************************************
112+
Build Clang-REPL with Out-of-Process JIT Execution
113+
***************************************************
114+
115+
To have `Out-of-Process JIT Execution` enabled, run following commands to build clang and clang-repl to support this feature:
116+
117+
.. note::
118+
119+
Only for Linux x86_64 and Macos arm64
120+
121+
.. code:: bash
122+
mkdir build
123+
cd build
124+
cmake -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" \
125+
-DLLVM_TARGETS_TO_BUILD="host;NVPTX" \
126+
-DCMAKE_BUILD_TYPE=Release \
127+
-DLLVM_ENABLE_ASSERTIONS=ON \
128+
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
129+
-DCLANG_ENABLE_ARCMT=OFF \
130+
-DCLANG_ENABLE_FORMAT=OFF \
131+
-DCLANG_ENABLE_BOOTSTRAP=OFF \
132+
../llvm
133+
134+
# For Linux x86_64
135+
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt-x86_64 --parallel $(nproc --all)
136+
# For MacOS arm64
137+
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt_osx --parallel $(sysctl -n hw.ncpu)
138+
102139
**************************************
103140
Build Cling and related dependencies
104141
**************************************
@@ -263,6 +300,10 @@ commands on Linux and MacOS
263300
cmake -DBUILD_SHARED_LIBS=ON -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR ..
264301
cmake --build . --target install --parallel $(nproc --all)
265302
303+
.. note::
304+
305+
Do make sure to pass ``DLLVM_BUILT_WITH_OOP_JIT=ON``, if you want to have out-of-process JIT execution feature enabled.
306+
266307
and
267308

268309
.. code:: powershell

include/CppInterOp/CppInterOp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstdint>
2020
#include <set>
2121
#include <string>
22+
#include <sys/types.h>
2223
#include <vector>
2324

2425
// The cross-platform CPPINTEROP_API macro definition
@@ -964,6 +965,12 @@ CPPINTEROP_API void CodeComplete(std::vector<std::string>& Results,
964965
///\returns 0 on success, non-zero on failure.
965966
CPPINTEROP_API int Undo(unsigned N = 1, TInterp_t interp = nullptr);
966967

968+
#ifndef _WIN32
969+
/// Returns the process ID of the executor process.
970+
/// \returns the PID of the executor process.
971+
CPPINTEROP_API pid_t GetExecutorPID();
972+
#endif
973+
967974
} // end namespace Cpp
968975

969976
#endif // CPPINTEROP_CPPINTEROP_H

lib/CppInterOp/Compatibility.h

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,24 @@ inline void codeComplete(std::vector<std::string>& Results,
202202

203203
#include "llvm/Support/Error.h"
204204

205+
#ifdef LLVM_BUILT_WITH_OOP_JIT
206+
#include "clang/Basic/Version.h"
207+
#include "llvm/TargetParser/Host.h"
208+
209+
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
210+
211+
#include <unistd.h>
212+
#endif
213+
214+
#include <algorithm>
215+
216+
static const llvm::ExitOnError ExitOnError;
217+
205218
namespace compat {
206219

207220
inline std::unique_ptr<clang::Interpreter>
208-
createClangInterpreter(std::vector<const char*>& args) {
221+
createClangInterpreter(std::vector<const char*>& args, int stdin_fd = 0,
222+
int stdout_fd = 1, int stderr_fd = 2) {
209223
auto has_arg = [](const char* x, llvm::StringRef match = "cuda") {
210224
llvm::StringRef Arg = x;
211225
Arg = Arg.trim().ltrim('-');
@@ -219,6 +233,15 @@ createClangInterpreter(std::vector<const char*>& args) {
219233
bool CudaEnabled = !gpu_args.empty();
220234
#endif
221235

236+
#if defined(_WIN32)
237+
bool outOfProcess = false;
238+
#else
239+
bool outOfProcess =
240+
std::any_of(args.begin(), args.end(), [](const char* arg) {
241+
return llvm::StringRef(arg).trim() == "--use-oop-jit";
242+
});
243+
#endif
244+
222245
clang::IncrementalCompilerBuilder CB;
223246
CB.SetCompilerArgs({args.begin(), it});
224247

@@ -243,11 +266,54 @@ createClangInterpreter(std::vector<const char*>& args) {
243266
(*ciOrErr)->LoadRequestedPlugins();
244267
if (CudaEnabled)
245268
DeviceCI->LoadRequestedPlugins();
269+
270+
#ifdef LLVM_BUILT_WITH_OOP_JIT
271+
272+
clang::Interpreter::JITConfig OutOfProcessConfig;
273+
if (outOfProcess) {
274+
OutOfProcessConfig.IsOutOfProcess = true;
275+
OutOfProcessConfig.OOPExecutor =
276+
std::string(LLVM_SOURCE_DIR) + "/build/bin/llvm-jitlink-executor";
277+
OutOfProcessConfig.UseSharedMemory = false;
278+
OutOfProcessConfig.SlabAllocateSize = 0;
279+
OutOfProcessConfig.CustomizeFork = [=] { // Lambda defined inline
280+
auto redirect = [](int from, int to) {
281+
if (from != to) {
282+
dup2(from, to);
283+
close(from);
284+
}
285+
};
286+
287+
redirect(stdin_fd, STDIN_FILENO);
288+
redirect(stdout_fd, STDOUT_FILENO);
289+
redirect(stderr_fd, STDERR_FILENO);
290+
291+
setvbuf(stdout, nullptr, _IONBF, 0);
292+
setvbuf(stderr, nullptr, _IONBF, 0);
293+
};
294+
OutOfProcessConfig.OrcRuntimePath =
295+
std::string(LLVM_SOURCE_DIR) +
296+
"/build/lib/clang/20/lib/darwin/liborc_rt_osx.a";
297+
}
298+
auto innerOrErr =
299+
CudaEnabled
300+
? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
301+
std::move(DeviceCI))
302+
: clang::Interpreter::create(std::move(*ciOrErr), OutOfProcessConfig);
303+
#else
304+
if (outOfProcess) {
305+
llvm::errs()
306+
<< "[CreateClangInterpreter]: No compatibility with out-of-process "
307+
"JIT. Running in-process JIT execution."
308+
<< "(To enable recompile CppInterOp with patch applied and change "
309+
"VERSION file to 1.8.1;dev."
310+
<< "\n";
311+
}
246312
auto innerOrErr =
247313
CudaEnabled ? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
248314
std::move(DeviceCI))
249315
: clang::Interpreter::create(std::move(*ciOrErr));
250-
316+
#endif
251317
if (!innerOrErr) {
252318
llvm::logAllUnhandledErrors(innerOrErr.takeError(), llvm::errs(),
253319
"Failed to build Interpreter:");

0 commit comments

Comments
 (0)