Skip to content

Commit

Permalink
Conditionally enable the llvmlite memory manager
Browse files Browse the repository at this point in the history
The default is to enable it on 64-bit ARM systems, since it solves the
problem they encounter, and disable it elsewhere, to minimise the risk
of an unintended side effect on platforms that don't need it.

This can be overridden by manually specifying the value of `use_lmm`
when creating the MCJIT compiler.
  • Loading branch information
gmarkall committed Dec 6, 2023
1 parent 75b103c commit 5e92f87
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 8 deletions.
6 changes: 5 additions & 1 deletion docs/source/user-guide/binding/execution-engine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ present a single execution engine, ``MCJIT``, is exposed.
Functions
=========

* .. function:: create_mcjit_compiler(module, target_machine)
* .. function:: create_mcjit_compiler(module, target_machine, use_lmm=None)

Create a MCJIT-powered engine from the given *module* and
*target_machine*.

*lmm* controls whether the llvmlite memory manager is used. If not
supplied, the default choice for the platform will be used (``True`` on
64-bit ARM systems, ``False`` otherwise).

* *module* does not need to contain any code.
* Returns a :class:`ExecutionEngine` instance.

Expand Down
13 changes: 8 additions & 5 deletions ffi/executionengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ LLVMPY_FinalizeObject(LLVMExecutionEngineRef EE) {

static LLVMExecutionEngineRef create_execution_engine(LLVMModuleRef M,
LLVMTargetMachineRef TM,
bool use_lmm,
const char **OutError) {
LLVMExecutionEngineRef ee = nullptr;

Expand All @@ -74,9 +75,11 @@ static LLVMExecutionEngineRef create_execution_engine(LLVMModuleRef M,
eb.setErrorStr(&err);
eb.setEngineKind(llvm::EngineKind::JIT);

std::unique_ptr<llvm::RTDyldMemoryManager> mm =
std::make_unique<llvm::LlvmliteMemoryManager>();
eb.setMCJITMemoryManager(std::move(mm));
if (use_lmm) {
std::unique_ptr<llvm::RTDyldMemoryManager> mm =
std::make_unique<llvm::LlvmliteMemoryManager>();
eb.setMCJITMemoryManager(std::move(mm));
}

/* EngineBuilder::create loads the current process symbols */
llvm::ExecutionEngine *engine = eb.create(llvm::unwrap(TM));
Expand All @@ -90,8 +93,8 @@ static LLVMExecutionEngineRef create_execution_engine(LLVMModuleRef M,

API_EXPORT(LLVMExecutionEngineRef)
LLVMPY_CreateMCJITCompiler(LLVMModuleRef M, LLVMTargetMachineRef TM,
const char **OutError) {
return create_execution_engine(M, TM, OutError);
bool use_lmm, const char **OutError) {
return create_execution_engine(M, TM, use_lmm, OutError);
}

API_EXPORT(uint64_t)
Expand Down
13 changes: 11 additions & 2 deletions llvmlite/binding/executionengine.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import platform
from ctypes import (POINTER, c_char_p, c_bool, c_void_p,
c_int, c_uint64, c_size_t, CFUNCTYPE, string_at, cast,
py_object, Structure)
Expand All @@ -9,14 +10,21 @@
ffi.lib.LLVMPY_LinkInMCJIT


def create_mcjit_compiler(module, target_machine):
def create_mcjit_compiler(module, target_machine, use_lmm=None):
"""
Create a MCJIT ExecutionEngine from the given *module* and
*target_machine*.
*lmm* controls whether the llvmlite memory manager is used. If not supplied,
the default choice for the platform will be used (``True`` on 64-bit ARM
systems, ``False`` otherwise).
"""
if use_lmm is None:
use_lmm = platform.machine() in ('arm64', 'aarch64')

with ffi.OutputString() as outerr:
engine = ffi.lib.LLVMPY_CreateMCJITCompiler(
module, target_machine, outerr)
module, target_machine, use_lmm, outerr)
if not engine:
raise RuntimeError(str(outerr))

Expand Down Expand Up @@ -239,6 +247,7 @@ def _dispose(self):
ffi.lib.LLVMPY_CreateMCJITCompiler.argtypes = [
ffi.LLVMModuleRef,
ffi.LLVMTargetMachineRef,
c_bool,
POINTER(c_char_p),
]
ffi.lib.LLVMPY_CreateMCJITCompiler.restype = ffi.LLVMExecutionEngineRef
Expand Down

0 comments on commit 5e92f87

Please sign in to comment.