Backend
backend
¶
JIT execution of LLVM IR modules.
The xdsl.jit.llvm.backend.LLVMJITBackend class compiles xDSL modules written in the
LLVM dialect to native code, using llvmlite’s MCJIT execution engine and makes their
signatures callable from Python.
To achieve this, the backend first derives the C function signature from the IR and then applies LLVM optimizations at level 2 by default.
For example, take the following add.mlir file, followed by a jit.py file which
compiles and executes it from the Python API:
builtin.module {
llvm.func @main() -> i32 {
%left = llvm.mlir.constant(21 : i32) : i32
%right = llvm.mlir.constant(21 : i32) : i32
%result = llvm.add %left, %right : i32
llvm.return %result : i32
}
}
# /// script
# requires-python = ">=3.11"
# dependencies = ["xdsl[llvm]"]
# ///
import sys
from xdsl.context import Context
from xdsl.parser import Parser
from xdsl.dialects import builtin, llvm
from xdsl.jit.llvm.backend import LLVMJITBackend
ctx = Context()
ctx.load_dialect(builtin.Builtin)
ctx.load_dialect(llvm.LLVM)
with open(sys.argv[1]) as f:
module = Parser(ctx, f.read()).parse_module()
backend = LLVMJITBackend(lowering=())
main = backend.jit(module, "main", ctx)
print(main.c_func())
We pass lowering=() to LLVMJITBackend, because the module is already in the LLVM
dialect and doesn’t need additional lowering tooling.
LLVMRawJITFunc
dataclass
¶
Bases: RawJITFunc
:class:RawJITFunc that retains LLVM MCJIT runtime objects.
The engine and related objects must remain referenced for as long as
c_func may be called.
Source code in xdsl/jit/llvm/backend.py
target: Target
instance-attribute
¶
target_machine: TargetMachine
instance-attribute
¶
backing_mod: ModuleRef
instance-attribute
¶
engine: ExecutionEngine
instance-attribute
¶
__init__(c_func_type: CFuncSignature, c_func: CFunc, target: Target, target_machine: TargetMachine, backing_mod: ModuleRef, engine: ExecutionEngine) -> None
¶
LLVMJITBackend
¶
Bases: JITBackend
:class:JITBackend using xDSL's LLVM converter and llvmlite MCJIT.
Runs :attr:lowering, requires symbol to name an llvm.FuncOp, then
converts the module and exposes the entry point through CFFI ABI mode.
Source code in xdsl/jit/llvm/backend.py
lowering: tuple[ModulePass, ...] = lowering
instance-attribute
¶
Pass pipeline applied before resolving symbol.
opt_level: Literal[0, 1, 2, 3] = opt_level
instance-attribute
¶
LLVM optimization level, applied to code generation and the IR pipeline.
__init__(lowering: tuple[ModulePass, ...] = (MLIROptPass(arguments=('--convert-arith-to-llvm', '--convert-func-to-llvm'), generic=True),), *, opt_level: Literal[0, 1, 2, 3] = 2)
¶
Construct the backend with the given lowering and opt_level.
Source code in xdsl/jit/llvm/backend.py
jit(mlir_module: builtin.ModuleOp, symbol: str, ir_context: Context) -> LLVMRawJITFunc
¶
Lower mlir_module, bind symbol, and return an :class:LLVMRawJITFunc.