Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/actions/Build_LLVM/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ runs:
git apply -v ../patches/llvm/clang${{ matrix.clang-runtime }}-*.patch
echo "Apply clang${{ matrix.clang-runtime }}-*.patch patches:"
fi
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
git apply -v ../patches/llvm/clang20-2-out-of-process-jit-execution.patch
echo "Apply out-of-process-jit-execution.patch:"
fi
cd build
cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects}}" \
-DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" \
Expand All @@ -64,6 +68,10 @@ runs:
-DLLVM_INCLUDE_TESTS=OFF \
../llvm
ninja clang clangInterpreter clangStaticAnalyzerCore -j ${{ env.ncpus }}
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
if [ "${{ matrix.os }}}" == "macos"* ]; then SUFFIX="_osx"; fi
ninja clang_repl llvm-jitlink-executor orc_rt${SUFFIX} -j ${{ env.ncpus }}
fi
cd ./tools/
rm -rf $(find . -maxdepth 1 ! -name "clang" ! -name ".")
cd ..
Expand Down
17 changes: 9 additions & 8 deletions .github/actions/Build_and_Test_CppInterOp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ runs:
../
else
cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCPPINTEROP_INCLUDE_DOCS=${{ matrix.documentation }} \
-DLLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm \
-DClang_DIR=$LLVM_BUILD_DIR/lib/cmake/clang \
-DBUILD_SHARED_LIBS=ON \
-DCODE_COVERAGE=${{ env.CODE_COVERAGE }} \
-DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR \
-DLLVM_ENABLE_WERROR=On \
../
-DCPPINTEROP_INCLUDE_DOCS=${{ matrix.documentation }} \
-DLLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm \
-DClang_DIR=$LLVM_BUILD_DIR/lib/cmake/clang \
-DBUILD_SHARED_LIBS=ON \
-DCODE_COVERAGE=${{ env.CODE_COVERAGE }} \
-DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR \
-DLLVM_ENABLE_WERROR=On \
-DCPPINTEROP_WITH_OOP_JIT=${{ matrix.oop-jit }} \
../
fi
docs_on=$(echo "${{ matrix.documentation }}" | tr '[:lower:]' '[:upper:]')
if [[ "${docs_on}" == "ON" ]]; then
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ jobs:
llvm_enable_projects: "clang"
llvm_targets_to_build: "host;NVPTX"
coverage: true
- name: ubu24-arm-gcc12-clang-repl-20-oop
os: ubuntu-24.04-arm
compiler: gcc-12
clang-runtime: '20'
cling: Off
cppyy: Off
llvm_enable_projects: "clang;compiler-rt"
llvm_targets_to_build: "host;NVPTX"
oop-jit: On
- name: ubu24-arm-gcc12-clang-repl-20
os: ubuntu-24.04-arm
compiler: gcc-12
Expand Down Expand Up @@ -132,6 +141,15 @@ jobs:
llvm_enable_projects: "clang"
llvm_targets_to_build: "host;NVPTX"
# MacOS Arm Jobs
- name: osx15-arm-clang-clang-repl-20-oop
os: macos-15
compiler: clang
clang-runtime: '20'
cling: Off
cppyy: Off
llvm_enable_projects: "clang;compiler-rt"
llvm_targets_to_build: "host"
oop-jit: On
- name: osx15-arm-clang-clang-repl-20
os: macos-15
compiler: clang
Expand Down Expand Up @@ -182,6 +200,15 @@ jobs:
llvm_enable_projects: "clang"
llvm_targets_to_build: "host;NVPTX"
# MacOS X86 Jobs
- name: osx13-x86-clang-clang-repl-20-oop
os: macos-13
compiler: clang
clang-runtime: '20'
cling: Off
cppyy: Off
llvm_enable_projects: "clang;compiler-rt"
llvm_targets_to_build: "host"
oop-jit: On
- name: osx13-x86-clang-clang-repl-20
os: macos-13
compiler: clang
Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,16 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

if(CPPINTEROP_WITH_OOP_JIT)
if(WIN32 OR EMSCRIPTEN)
message(FATAL_ERROR "CPPINTEROP_WITH_OOP_JIT is not supported on Windows or Emscripten platforms.")
endif()
add_definitions(-DCPPINTEROP_WITH_OOP_JIT)
endif()

string(REGEX REPLACE "/build/lib/cmake/llvm$" "" LLVM_SOURCE_DIR "${LLVM_DIR}")
add_definitions(-DLLVM_SOURCE_DIR="${LLVM_SOURCE_DIR}")

# If the llvm sources are present add them with higher priority.
if (LLVM_BUILD_MAIN_SRC_DIR)
# LLVM_INCLUDE_DIRS contains the include paths to both LLVM's source and
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ git apply -v clang{version}-*.patch

on Windows.

If you want to have out-of-process JIT execution enabled in CppInterOp, then apply this patch on Linux and MacOS environment.
> Note that this patch will not work for Windows because out-of-process JIT execution is currently implemented for Linux and MacOS only.

```bash
git apply -v ../CppInterOp/patches/llvm/clang20-2-out-of-process-jit-execution.patch
```

##### Build Clang-REPL

Clang-REPL is an interpreter that CppInterOp works alongside. Build Clang (and
Expand Down Expand Up @@ -175,6 +182,30 @@ $env:LLVM_DIR= $PWD.Path
cd ..\
```

##### Build Clang-REPL with Out-of-Process JIT Execution

To have ``Out-of-Process JIT Execution`` enabled, run following commands to build clang and clang-repl to support this feature:
> Only for Linux and Macos
```bash
mkdir build
cd build
cmake -DLLVM_ENABLE_PROJECTS="clang;compiler-rt \
-DLLVM_TARGETS_TO_BUILD="host;NVPTX" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
-DCLANG_ENABLE_ARCMT=OFF \
-DCLANG_ENABLE_FORMAT=OFF \
-DCLANG_ENABLE_BOOTSTRAP=OFF \
../llvm

## For Linux
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt --parallel $(nproc --all)

## For MacOS
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt_osx --parallel $(sysctl -n hw.ncpu)
```

#### Build Cling and related dependencies

Besides the Clang-REPL interpreter, CppInterOp also works alongside the Cling
Expand Down Expand Up @@ -324,6 +355,8 @@ cmake -DBUILD_SHARED_LIBS=ON -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_D
cmake --build . --target install --parallel $(nproc --all)
```

> Do make sure to add ``-DCPPINTEROP_WITH_OOP_JIT=ON``, if you want to have out-of-process JIT execution feature enabled.

and

```powershell
Expand Down
43 changes: 43 additions & 0 deletions docs/InstallationAndUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ and

on Windows.

If you want to have out-of-process JIT execution enabled in CppInterOp, then apply this patch on Linux and MacOS environment.
.. note::

This patch will not work for Windows because out-of-process JIT execution is currently implemented for Linux and MacOS only.

.. code:: bash

git apply -v ../CppInterOp/patches/llvm/clang20-2-out-of-process-jit-execution.patch

******************
Build Clang-REPL
******************
Expand Down Expand Up @@ -116,6 +125,36 @@ On Windows you execute the following
$env:LLVM_DIR= $PWD.Path
cd ..\

***************************************************
Build Clang-REPL with Out-of-Process JIT Execution
***************************************************

To have `Out-of-Process JIT Execution` enabled, run following commands to build clang and clang-repl to support this feature:

.. note::

Only for Linux and Macos

.. code:: bash

mkdir build
cd build
cmake -DLLVM_ENABLE_PROJECTS="clang;compiler-rt \
-DLLVM_TARGETS_TO_BUILD="host;NVPTX" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
-DCLANG_ENABLE_ARCMT=OFF \
-DCLANG_ENABLE_FORMAT=OFF \
-DCLANG_ENABLE_BOOTSTRAP=OFF \
../llvm

# For Linux
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt --parallel $(nproc --all)

# For MacOS
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt_osx --parallel $(sysctl -n hw.ncpu)

**************************************
Build Cling and related dependencies
**************************************
Expand Down Expand Up @@ -280,6 +319,10 @@ commands on Linux and MacOS
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 ..
cmake --build . --target install --parallel $(nproc --all)

.. note::

Do make sure to add `-DCPPINTEROP_WITH_OOP_JIT=ON`, if you want to have out-of-process JIT execution feature enabled.

and

.. code:: powershell
Expand Down
6 changes: 5 additions & 1 deletion include/CppInterOp/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ CPPINTEROP_API void GetOperator(TCppScope_t scope, Operator op,
///\returns nullptr on failure.
CPPINTEROP_API TInterp_t
CreateInterpreter(const std::vector<const char*>& Args = {},
const std::vector<const char*>& GpuArgs = {});
const std::vector<const char*>& GpuArgs = {}, bool outOfProcess = false);

/// Deletes an instance of an interpreter.
///\param[in] I - the interpreter to be deleted, if nullptr, deletes the last.
Expand Down Expand Up @@ -901,6 +901,10 @@ CPPINTEROP_API void CodeComplete(std::vector<std::string>& Results,
///\returns 0 on success, non-zero on failure.
CPPINTEROP_API int Undo(unsigned N = 1);

#ifdef CPPINTEROP_WITH_OOP_JIT
CPPINTEROP_API pid_t GetExecutorPID();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "pid_t" is directly included [misc-include-cleaner]

include/CppInterOp/CppInterOp.h:21:

- #include <vector>
+ #include <sys/types.h>
+ #include <vector>

#endif // CPPINTEROP_WITH_OOP_JIT

} // end namespace Cpp

#endif // CPPINTEROP_CPPINTEROP_H
68 changes: 66 additions & 2 deletions lib/CppInterOp/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,22 @@ inline void codeComplete(std::vector<std::string>& Results,

#include "llvm/Support/Error.h"

#include <vector>

#ifdef CPPINTEROP_WITH_OOP_JIT
#include "clang/Basic/Version.h"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: #includes are not sorted properly [llvm-include-order]

Suggested change
#include "clang/Basic/Version.h"
#include "clang/Basic/Version.h"
#include "clang/Interpreter/RemoteJITUtils.h"

#include "clang/Interpreter/RemoteJITUtils.h"
#include "llvm/TargetParser/Host.h"

#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
#endif

static const llvm::ExitOnError ExitOnError;

namespace compat {

inline std::unique_ptr<clang::Interpreter>
createClangInterpreter(std::vector<const char*>& args) {
createClangInterpreter(std::vector<const char*>& args, bool outOfProcess) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::vector" is directly included [misc-include-cleaner]

lib/CppInterOp/Compatibility.h:10:

+ #include <vector>

auto has_arg = [](const char* x, llvm::StringRef match = "cuda") {
llvm::StringRef Arg = x;
Arg = Arg.trim().ltrim('-');
Expand Down Expand Up @@ -246,16 +258,62 @@ createClangInterpreter(std::vector<const char*>& args) {
(*ciOrErr)->LoadRequestedPlugins();
if (CudaEnabled)
DeviceCI->LoadRequestedPlugins();

#ifdef CPPINTEROP_WITH_OOP_JIT
std::unique_ptr<llvm::orc::LLJITBuilder> JB;

if (outOfProcess) {
std::string OOPExecutor =
std::string(LLVM_SOURCE_DIR) + "/build/bin/llvm-jitlink-executor";
bool UseSharedMemory = false;
std::string SlabAllocateSizeString = "";
std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC;
EPC = ExitOnError(
launchExecutor(OOPExecutor, UseSharedMemory, SlabAllocateSizeString));

#ifdef __APPLE__
std::string OrcRuntimePath =
std::string(LLVM_SOURCE_DIR) +
"/build/lib/clang/20/lib/darwin/liborc_rt_osx.a";
#else
std::string OrcRuntimePath =
std::string(LLVM_SOURCE_DIR) +
"/build/lib/x86_64-unknown-linux-gnu/liborc_rt.a";
#endif
if (EPC) {

CB.SetTargetTriple(EPC->getTargetTriple().getTriple());
JB = ExitOnError(clang::Interpreter::createLLJITBuilder(std::move(EPC),
OrcRuntimePath));
}
}

auto innerOrErr =
CudaEnabled
? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
std::move(DeviceCI))
: clang::Interpreter::create(std::move(*ciOrErr), std::move(JB));
#else
if (outOfProcess) {
llvm::errs()
<< "[CreateClangInterpreter]: No compatibility with out-of-process JIT"
<< "(To enable recompile CppInterOp with "
"`-DCPPINTEROP_WITH_OOP_JIT=ON`)"
<< "\n";
return nullptr;
}
auto innerOrErr =
CudaEnabled ? clang::Interpreter::createWithCUDA(std::move(*ciOrErr),
std::move(DeviceCI))
: clang::Interpreter::create(std::move(*ciOrErr));
#endif

if (!innerOrErr) {
llvm::logAllUnhandledErrors(innerOrErr.takeError(), llvm::errs(),
"Failed to build Interpreter:");
return nullptr;
}

if (CudaEnabled) {
if (auto Err = (*innerOrErr)->LoadDynamicLibrary("libcudart.so")) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
Expand Down Expand Up @@ -371,6 +429,12 @@ inline void codeComplete(std::vector<std::string>& Results,
#endif
}

#ifdef CPPINTEROP_WITH_OOP_JIT
inline pid_t getExecutorPID() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "pid_t" is directly included [misc-include-cleaner]

lib/CppInterOp/Compatibility.h:10:

+ #include <sched.h>

return getLastLaunchedExecutorPID();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'getLastLaunchedExecutorPID' [clang-diagnostic-error]

  return getLastLaunchedExecutorPID();
         ^

}
#endif // CPPINTEROP_WITH_OOP_JIT

} // namespace compat

#include "CppInterOpInterpreter.h"
Expand All @@ -395,7 +459,7 @@ class SynthesizingCodeRAII {
"Failed to generate PTU:");
}
};
}
} // namespace compat

#endif // CPPINTEROP_USE_REPL

Expand Down
10 changes: 8 additions & 2 deletions lib/CppInterOp/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,7 @@ static std::string MakeResourcesPath() {
} // namespace

TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
const std::vector<const char*>& GpuArgs /*={}*/) {
const std::vector<const char*>& GpuArgs /*={}*/, bool outOfProcess) {
std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
std::string ResourceDir = MakeResourcesPath();
std::vector<const char*> ClingArgv = {"-resource-dir", ResourceDir.c_str(),
Expand Down Expand Up @@ -3075,7 +3075,7 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]);
#else
auto Interp = compat::Interpreter::create(static_cast<int>(ClingArgv.size()),
ClingArgv.data());
ClingArgv.data(), nullptr, {}, nullptr, true, outOfProcess);
if (!Interp)
return nullptr;
auto* I = Interp.release();
Expand Down Expand Up @@ -3909,4 +3909,10 @@ int Undo(unsigned N) {
#endif
}

#ifdef CPPINTEROP_WITH_OOP_JIT
pid_t GetExecutorPID() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "pid_t" is directly included [misc-include-cleaner]

lib/CppInterOp/CppInterOp.cpp:40:

- #if CLANG_VERSION_MAJOR >= 19
+ #include <sys/types.h>
+ #if CLANG_VERSION_MAJOR >= 19

return compat::getExecutorPID();
}
#endif // CPPINTEROP_WITH_OOP_JIT

} // end namespace Cpp
Loading
Loading