当前位置: 首页 > 工具软件 > llvmpy > 使用案例 >

在Python中使用LLVM接口:llvmpy和llvmlite

蔡宏大
2023-12-01

1.过时的llvmpy

llvmpy是llvm C ++库的Python包装器,允许简单访问编译器工具。
但是这个库已经不再更新了,只支持LLVM 3.3,不支持更新的版本。
有一篇好文章可以阅读:Let’s Write an LLVM Specializer for Python! (Stephen Diehl)

2.llvmlite

项目的GitHub地址:numba/llvmlite: A lightweight LLVM python binding for writing JIT compilers
对应版本如下:

llvmlite versionscompatible LLVM versions
0.29.0 - …7.0.x, 7.1.x, 8.0.x
0.27.0 - 0.28.07.0.x
0.23.0 - 0.26.06.0.x
0.21.0 - 0.22.05.0.x
0.17.0 - 0.20.04.0.x
0.16.0 - 0.17.03.9.x
0.13.0 - 0.15.03.8.x
0.9.0 - 0.12.13.7.x
0.6.0 - 0.8.03.6.x
0.1.0 - 0.5.13.5.x

我使用的LLVM版本是3.9,所以我下载0.16.0版本的llvmlite :

apt install libedit-dev
alias llvm-config="llvm-config-3.9"
export LLVM_CONFIG="/usr/bin/llvm-config-3.9"
pip3 install llvmlite==0.16.0
python3 -m llvmlite.tests

现在就可以使用了,示例代码如下:

from __future__ import print_function

from ctypes import CFUNCTYPE, c_double

import llvmlite.binding as llvm


# All these initializations are required for code generation!
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()  # yes, even this one

llvm_ir = """
   ; ModuleID = "examples/ir_fpadd.py"
   target triple = "unknown-unknown-unknown"
   target datalayout = ""

   define double @"fpadd"(double %".1", double %".2")
   {
   entry:
     %"res" = fadd double %".1", %".2"
     ret double %"res"
   }
   """

def create_execution_engine():
    """
    Create an ExecutionEngine suitable for JIT code generation on
    the host CPU.  The engine is reusable for an arbitrary number of
    modules.
    """
    # Create a target machine representing the host
    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()
    # And an execution engine with an empty backing module
    backing_mod = llvm.parse_assembly("")
    engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
    return engine


def compile_ir(engine, llvm_ir):
    """
    Compile the LLVM IR string with the given engine.
    The compiled module object is returned.
    """
    # Create a LLVM module object from the IR
    mod = llvm.parse_assembly(llvm_ir)
    mod.verify()
    # Now add the module and make sure it is ready for execution
    engine.add_module(mod)
    engine.finalize_object()
    return mod


engine = create_execution_engine()
mod = compile_ir(engine, llvm_ir)

# Look up the function pointer (a Python int)
func_ptr = engine.get_function_address("fpadd")

# Run the function via ctypes
cfunc = CFUNCTYPE(c_double, c_double, c_double)(func_ptr)
res = cfunc(1.0, 3.5)
print("fpadd(...) =", res)

 类似资料: