Python bindings for LLVM auto-generated from the LLVM-C API
The main goal of
llvmcpyis to provide Python bindings for the LLVM project that are fast and require the lowest possible maintainance effort. To achive this, we use CFFI to parse the (slightly adapted) header files for the
LLVM-C API_ and automatically generate a set of classes and functions to interact with them in a Pythonic way.
This project is in an early stage, but allows you to run the following code::
import sys from llvmcpy.llvm import *
buffer = create_memory_buffer_with_contents_of_file(sys.argv) context = get_global_context() module = context.parse_ir(buffer) for function in module.iter_functions(): for bb in function.iter_basic_blocks(): for instruction in bb.iter_instructions(): instruction.dump()
It has been tested with LLVM 3.4, 3.8 and 3.9. Supporting older and newer versions of the
LLVM-C API_ should be basically effortless.
To try it out install LLVM and get
sudo apt-get install llvm pip install llvmcpy
Naming of the generated classes/functions
The basic idea behind this project is to take the
LLVM-C API_ function, create a class for each data type and create a method for that class for each function in the API taking an argument of that data type as first argument.
This means that the following functions::
LLVMModuleRef LLVMCloneModule (LLVMModuleRef M)
class Module(object): def clone(self): # ...
Note the change in the case. Use
help(Module.clone)to see which
LLVM-C API_ function a certain method is using.
Each class in
llvmcpyis basically a wrapper around a pointer to an LLVM object.
If an API function doesn't take an LLVM object as a first argument, it will be part of the
llvmmodule. Moreover, we also have some also generated properties and generators for certain well known patterns in the API.
:Properties: For each function starting with
LLVM-C API_, we generate a property. For example, consider the following two functions::
void LLVMSetValueName (LLVMValueRef Val, const char *Name) const char* LLVMGetValueName(LLVMValueRef Val)
In `llvmcpy` the `Get`/`Set` prefixes disappear, along with `Value` (the name of the class) and you can use them as properties of the `Value` class, e.g.:: my_value.name = "sum" print my_value.name
LLVM-C API_ has a recurrent pattern which allows you to navigate through the hierarchy of its class hierarchy, i.e. the pair of
BasicBlockand so on.
llvmcpyidentifies these patterns and produces a generator method which allows you to iterate over these objects in a Pythonic way::
for function in module.iter_functions(): for bb in function.iter_basic_blocks(): for instruction in bb.iter_instructions(): # ...
Where are my bindings?
Bindings are automatically generated in a lazy way. Multiple installations of LLVM are supported, just set the
LLVM_CONFIGenvironment variable to the
llvm-configprogram in the
bin/directory of your LLVM installation and everything should work fine.
The bindings are generated in a Python script which is stored in
~/.cache/) in a directory whose name is obtained by hashing the full path of the output of
llvm-config --prefixconcatenated with the LLVM version number. For example, for LLVM 3.9.0 installed in
/usryou'll find the API bindings in
To generate the bindings a working C preprocessor must be available in the system. By default
cpp(the C preprocessor part of GCC) is used. If it's not available we check if
clangis available in the LLVM installation and use it.
License and credits
This project is developed and maintained by Alessandro Di Federico ([email protected]) as a part of the
rev.ng_ project, and it's released under the MIT license.
.. rev.ng: https://rev.ng/ .. _LLVM-C API: http://llvm.org/docs/doxygen/html/group_LLVMC.html