Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
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
15 changes: 15 additions & 0 deletions .github/actions/Build_LLVM/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ 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-1-out-of-process.patch
echo "Apply clang20-1-out-of-process.patch:"
echo "OOP_SUFFIX=-oop" >> $GITHUB_ENV
else
echo "OOP_SUFFIX=" >> $GITHUB_ENV
fi
cd build
cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects}}" \
-DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" \
Expand All @@ -64,6 +71,14 @@ 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"
elif [[ "${{ matrix.os }}" == linux* ]]; then
SUFFIX="-x86_64"
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
6 changes: 6 additions & 0 deletions .github/actions/Build_and_Test_CppInterOp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ runs:
export CPPINTEROP_DIR="$CB_PYTHON_DIR/cppyy_backend"

# Build CppInterOp next to cling and llvm-project.
if [[ "${{ matrix.oop-jit }}" == "On" ]]; then
if [[ -f VERSION ]]; then
sed -i.bak 's/1\.8\.0;dev/1.8.1;dev/' VERSION
rm -f VERSION.bak
fi
fi
mkdir build && cd build
export CPPINTEROP_BUILD_DIR=$PWD
cling_on=$(echo "${{ matrix.cling }}" | tr '[:lower:]' '[:upper:]')
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,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
22 changes: 16 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,26 @@ if (CPPINTEROP_USE_CLING)
else()
set(CLANG_MIN_SUPPORTED 16.0)
endif(CPPINTEROP_USE_CLING)
set(CLANG_MAX_SUPPORTED "20.1.x")
set(CLANG_VERSION_UPPER_BOUND 21.0.0)
set(CLANG_MAX_SUPPORTED "21.1.x")
set(CLANG_VERSION_UPPER_BOUND 22.0.0)
if (CPPINTEROP_USE_CLING)
set(LLD_MIN_SUPPORTED 18.0)
else()
set(LLD_MIN_SUPPORTED 16.0)
endif(CPPINTEROP_USE_CLING)
set(LLD_MAX_SUPPORTED "20.1.x")
set(LLD_VERSION_UPPER_BOUND 21.0.0)
set(LLD_MAX_SUPPORTED "21.1.x")
set(LLD_VERSION_UPPER_BOUND 22.0.0)
if (CPPINTEROP_USE_CLING)
set(LLVM_MIN_SUPPORTED 18.0)
else()
set(LLVM_MIN_SUPPORTED 16.0)
endif(CPPINTEROP_USE_CLING)
set(LLVM_MAX_SUPPORTED "20.1.x")
set(LLVM_VERSION_UPPER_BOUND 21.0.0)
set(LLVM_MAX_SUPPORTED "21.1.x")
set(LLVM_VERSION_UPPER_BOUND 22.0.0)

## Set Cmake packages search order


set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)

Expand Down Expand Up @@ -310,6 +311,9 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

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 Expand Up @@ -391,10 +395,16 @@ string(REPLACE "-Wcovered-switch-default" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}

file(STRINGS "VERSION" CPPINTEROP_VERSION)
string(REPLACE "." ";" VERSION_LIST "${CPPINTEROP_VERSION}")
string(REPLACE "\;" ";" VERSION_LIST "${VERSION_LIST}")

list(GET VERSION_LIST 0 CPPINTEROP_VERSION_MAJOR)
list(GET VERSION_LIST 1 CPPINTEROP_VERSION_MINOR)
list(GET VERSION_LIST 2 CPPINTEROP_VERSION_PATCH)

if(NOT CPPINTEROP_VERSION_PATCH STREQUAL "0")
add_definitions(-DCPPINTEROP_VERSION_PATCH)
endif()

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/CppInterOp/CppInterOpConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/CppInterOp/CppInterOpConfig.cmake
Expand Down
31 changes: 31 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-1-out-of-process.patch
```

##### Build Clang-REPL

Clang-REPL is an interpreter that CppInterOp works alongside. Build Clang (and
Expand Down Expand Up @@ -175,6 +182,28 @@ $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-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

Besides the Clang-REPL interpreter, CppInterOp also works alongside the Cling
Expand Down Expand Up @@ -326,6 +355,8 @@ cmake --build . --target install --parallel $(nproc --all)

and

> Do make sure to apply the patch and change VERSION file to ``1.8.1;dev``, if you want to have out-of-process JIT execution feature enabled.

```powershell
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 ..
cmake --build . --target install --parallel $env:ncpus
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-1-out-of-process.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-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 apply the patch and change VERSION file to ``1.8.1;dev``, if you want to have out-of-process JIT execution feature enabled.

and

.. code:: powershell
Expand Down
8 changes: 7 additions & 1 deletion include/CppInterOp/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <set>
#include <string>
#include <vector>
#include <sys/types.h>

// The cross-platform CPPINTEROP_API macro definition
#if defined _WIN32 || defined __CYGWIN__
Expand Down Expand Up @@ -667,7 +668,8 @@ 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 = {},
int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);

/// Deletes an instance of an interpreter.
///\param[in] I - the interpreter to be deleted, if nullptr, deletes the last.
Expand Down Expand Up @@ -903,6 +905,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);

/// Returns the process ID of the executor process.
/// \returns the PID of the executor process.
CPPINTEROP_API pid_t GetExecutorPID();

} // end namespace Cpp

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

#include "llvm/Support/Error.h"

#ifdef CPPINTEROP_VERSION_PATCH
#include "clang/Basic/Version.h"
#include "clang/Interpreter/RemoteJITUtils.h"
#include "llvm/TargetParser/Host.h"

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

#include <algorithm>

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, int stdin_fd = 0,
int stdout_fd = 1, int stderr_fd = 2) {
auto has_arg = [](const char* x, llvm::StringRef match = "cuda") {
llvm::StringRef Arg = x;
Arg = Arg.trim().ltrim('-');
Expand All @@ -222,6 +235,15 @@ createClangInterpreter(std::vector<const char*>& args) {
bool CudaEnabled = !gpu_args.empty();
#endif

#if defined(_WIN32)
bool outOfProcess = false;
#else
bool outOfProcess =
std::any_of(args.begin(), args.end(), [](const char* arg) {
return llvm::StringRef(arg).trim() == "--use-oop-jit";
});
#endif

clang::IncrementalCompilerBuilder CB;
CB.SetCompilerArgs({args.begin(), it});

Expand All @@ -246,16 +268,61 @@ createClangInterpreter(std::vector<const char*>& args) {
(*ciOrErr)->LoadRequestedPlugins();
if (CudaEnabled)
DeviceCI->LoadRequestedPlugins();

#ifdef CPPINTEROP_VERSION_PATCH
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, stdin_fd,
stdout_fd, stderr_fd));

#ifdef __APPLE__
std::string OrcRuntimePath = std::string(LLVM_SOURCE_DIR) +
"/build/lib/clang/" + std::to_string(LLVM_VERSION_MAJOR) +
"/lib/darwin/liborc_rt_osx.a";
#else
std::string OrcRuntimePath = std::string(LLVM_SOURCE_DIR) +
"/build/lib/clang/" + std::to_string(LLVM_VERSION_MAJOR) +
"/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. Running in-process JIT execution."
<< "(To enable recompile CppInterOp with patch applied and change "
"VERSION file to 1.8.1;dev."
<< "\n";
}
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 +438,10 @@ inline void codeComplete(std::vector<std::string>& Results,
#endif
}

#ifdef CPPINTEROP_VERSION_PATCH
inline pid_t getExecutorPID() { return /*llvm*/ getLastLaunchedExecutorPID(); }
#endif

} // namespace compat

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

#endif // CPPINTEROP_USE_REPL

Expand Down
Loading
Loading