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 \

Choose a reason for hiding this comment

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

Suggested change
cmake -DLLVM_ENABLE_PROJECTS="clang;compiler-rt \
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 \

Choose a reason for hiding this comment

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

.

-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)

Choose a reason for hiding this comment

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

In my system (Linux - X86-64) the target is:

Suggested change
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt --parallel $(nproc --all)
cmake --build . --target clang clang-repl llvm-jitlink-executor orc_rt-x86_64 --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);

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>


// CPPINTEROP_API void SendInputToChild(const std::string& input);

Choose a reason for hiding this comment

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

If this is not yet implemented, it should not be part of the PR. Even as a comment.


} // end namespace Cpp

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

#include "llvm/Support/Error.h"

#include <vector>

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]

#include <vector>
^

this fix will not be applied because it overlaps with another fix

#include <unistd.h>

Choose a reason for hiding this comment

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

warning: included header unistd.h is not used directly [misc-include-cleaner]

Suggested change

#ifdef CPPINTEROP_WITH_OOP_JIT
#include "clang/Basic/Version.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 {

static int m_child_stdout_fd = -1;

Choose a reason for hiding this comment

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

warning: variable 'm_child_stdout_fd' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

static int m_child_stdout_fd = -1;
           ^

static int m_child_stderr_fd = -1;

Choose a reason for hiding this comment

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

warning: variable 'm_child_stderr_fd' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

static int m_child_stderr_fd = -1;
           ^

// static int m_child_stdin_fd = -1;

inline std::unique_ptr<clang::Interpreter>
createClangInterpreter(std::vector<const char*>& args) {
createClangInterpreter(std::vector<const char*>& args, bool outOfProcess) {
auto has_arg = [](const char* x, llvm::StringRef match = "cuda") {
llvm::StringRef Arg = x;
Arg = Arg.trim().ltrim('-');
Expand Down Expand Up @@ -246,16 +263,78 @@ 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;

// Create pipes for child process I/O control
int stdout_pipe[2], stderr_pipe[2], stdin_pipe[2];
if (pipe(stdout_pipe) != 0 || pipe(stderr_pipe) != 0 || pipe(stdin_pipe)) {
llvm::errs() << "Failed to create pipes for child process I/O\n";
return nullptr;
}

EPC = ExitOnError(
launchExecutor(OOPExecutor, UseSharedMemory, SlabAllocateSizeString,
/*stdin_pipe[0]*/0, stdout_pipe[1], stderr_pipe[1]));

Choose a reason for hiding this comment

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

Why are you not yet using the stdin pipe?


close(stdout_pipe[1]);
close(stderr_pipe[1]);
// close(stdin_pipe[1]);

m_child_stdout_fd = stdout_pipe[0];
m_child_stderr_fd = stderr_pipe[0];
// m_child_stdin_fd = stdin_pipe[1];

#ifdef __APPLE__
std::string OrcRuntimePath =
std::string(LLVM_SOURCE_DIR) +
"/build/lib/clang/20/lib/darwin/liborc_rt_osx.a";

Choose a reason for hiding this comment

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

Suggested change
"/build/lib/clang/20/lib/darwin/liborc_rt_osx.a";
"/build/lib/clang/LLVM_VERSION_MAJOR/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";

Choose a reason for hiding this comment

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

The path on my Linux machine is:

Suggested change
"/build/lib/x86_64-unknown-linux-gnu/liborc_rt.a";
"/build/lib/clang/20/lib/linux/liborc_rt-x86_64.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 +450,12 @@ inline void codeComplete(std::vector<std::string>& Results,
#endif
}

#ifdef CPPINTEROP_WITH_OOP_JIT
inline pid_t getExecutorPID() {
return getLastLaunchedExecutorPID();

Choose a reason for hiding this comment

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

Can we specify the namespace to make it clear that getLastLaunchedExecutorPID is from LLVM.

}
#endif // CPPINTEROP_WITH_OOP_JIT

} // namespace compat

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

#endif // CPPINTEROP_USE_REPL

Expand Down
Loading
Loading