I tried to output LLVM IR with Python

Python has a package called llvmlite, which was very useful! What a LLVM IR can easily output! I think it's a great first step for LLVM.

That's why I'll try "installing llvmlite"-"trying it a little"!

environment

I virtualized and installed Ubuntu on Windows 7 with VirtualBox. Basically, if it is an Ubuntu-derived distribution, it will work. In fact, I installed it on Linux Mint 17.3 (Cinnamon 64bit) with the same procedure, but it works fine.

For the time being, prepare what you need with apt-get

Prepare to build LLVM and Python3 development environment.

$ sudo apt-get install build-essential cmake python3-dev python3-pip python3-setuptools zlib1g-dev libtool

Build LLVM

Download from the site

llvmlite requires LLVM 3.6. You can get it with apt-get, but I want to manage the installation directory by myself, so I build it myself.

$ wget http://llvm.org/releases/3.6.2/llvm-3.6.2.src.tar.xz

Build

I like to use cmake. Building LLVM takes a bit of time, so wait patiently. (Use make -j4 for parallel build)

$ tar xvf llvm-3.6.2.src.tar.xz
$ cd llvm-3.6.2.src
$ mkdir build
$ cd build
$ cmake -D CMAKE_INSTALL_PREFIX=/usr/local/llvm-3.6 ..
$ make
$ sudo make install

bashrc settings

Do it through the path to LLVM

export LLVM_HOME=/usr/local/llvm-3.6
export PATH=${LLVM_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${LLVM_HOME}/lib:${LD_LIBRARY_PATH}
export LLVM_CONFIG=${LLVM_HOME}/bin/llvm-config

#Also set the C include path just in case
export C_INCLUDE_PATH=${LLVM_HOME}/include:${C_INCLUDE_PATH}
export CPLUS_INCLUDE_PATH=${LLVM_HOME}/include:${CPLUS_INCLUDE_PATH}

check

$ llvm-config --version
3.6.2

Install llvmlite

Prepare Python library

Install what you probably need. Some may be unnecessary. The Python library is apt-get, pip, and there are many ways to install it. Only scipy and matplotlib couldn't be pip, so I installed it with apt-get.

$ sudo -E pip3 install numpy
$ sudo apt-get install python3-scipy python3-matplotlib
$ sudo -E pip3 install pandas statsmodels sympy

Install llvmlite

Quickly install llvmlite with pip

$ sudo -E pip3 install llvmlite

That's it!

Trial

Trial run

Let's try it out! If you can run the following Python file, it's working!

Below is a sample I made appropriately.

sample

from ctypes import CFUNCTYPE, c_int

import llvmlite.ir as ll
import llvmlite.binding as llvm

"""
Make this with LLVM IR.
def func(x, y):
    a = x
    b = y
    c = 1000
    d = a
    return a + b + c + d
"""

#Initialization
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()

i32 = ll.IntType(32)

# int func(int, int)
fnty = ll.FunctionType(i32, [i32, i32])
module = ll.Module()
func = ll.Function(module, fnty, name="func")
bb_entry = func.append_basic_block()

builder = ll.IRBuilder()
builder.position_at_end(bb_entry)

#Argument x, y
x, y = func.args

#Variable a,b,c,Define d
ptr_a = builder.alloca(i32)
ptr_b = builder.alloca(i32)
ptr_c = builder.alloca(i32)
ptr_d = builder.alloca(i32)

# store
builder.store(x, ptr_a)
builder.store(y, ptr_b)
builder.store(ll.Constant(i32, 1000), ptr_c)

# load
a = builder.load(ptr_a)
b = builder.load(ptr_b)
c = builder.load(ptr_c)

#Also store
builder.store(a, ptr_d)

#Add and return
ret1 = builder.add(a, b, name="res")
ret2 = builder.add(ret1, c, name="res2")
ret3 = builder.add(ret2, builder.load(ptr_d), name="res3")
builder.ret(ret3)

llvm_ir = str(module)
llvm_ir_parsed = llvm.parse_assembly(llvm_ir)

print("== LLVM IR ====================")
print(llvm_ir_parsed)

# pass
pmb = llvm.create_pass_manager_builder()
pmb.opt_level = 1
pm = llvm.create_module_pass_manager()
pmb.populate(pm)

pm.run(llvm_ir_parsed)

print("== LLVM IR(opt) ===============")
print(llvm_ir_parsed)

target_machine = llvm.Target.from_default_triple().create_target_machine()

print("== Result =====================")
with llvm.create_mcjit_compiler(llvm_ir_parsed, target_machine) as ee:
    ee.finalize_object()
    cfptr = ee.get_function_address("func")

    cfunc = CFUNCTYPE(c_int, c_int, c_int)(cfptr)
    res = cfunc(100, 2)

    print("res: " + str(res))

Execution result

== LLVM IR ====================
; ModuleID = '<string>'
target triple = "unknown-unknown-unknown"

define i32 @func(i32 %.1, i32 %.2) {
.4:
  %.5 = alloca i32
  %.6 = alloca i32
  %.7 = alloca i32
  %.8 = alloca i32
  store i32 %.1, i32* %.5
  store i32 %.2, i32* %.6
  store i32 1000, i32* %.7
  %.12 = load i32* %.5
  %.13 = load i32* %.6
  %.14 = load i32* %.7
  store i32 %.12, i32* %.8
  %res = add i32 %.12, %.13
  %res2 = add i32 %res, %.14
  %.16 = load i32* %.8
  %res3 = add i32 %res2, %.16
  ret i32 %res3
}

== LLVM IR(opt) ===============
; ModuleID = '<string>'
target triple = "unknown-unknown-unknown"

; Function Attrs: nounwind readnone
define i32 @func(i32 %.1, i32 %.2) #0 {
.4:
  %factor = shl i32 %.1, 1
  %res2 = add i32 %.2, 1000
  %res3 = add i32 %res2, %factor
  ret i32 %res3
}

attributes #0 = { nounwind readnone }

== Result =====================
res: 1202

Looking at LLVM IR (opt). You can see that there is no useless part such as store.

example There is also an example on the original Github, so you can refer to it. https://github.com/numba/llvmlite

Other references

The LLVM head family has a tutorial called kaleidoscope. The following is an implementation of it with llvmlite, which is very helpful, so I will introduce it.

https://github.com/eliben/pykaleidoscope

Recommended Posts

I tried to output LLVM IR with Python
I tried to get CloudWatch data with Python
I tried to automate sushi making with python
I tried fp-growth with python
I tried scraping with Python
I tried gRPC with Python
I tried scraping with python
I tried to implement Minesweeper on terminal with python
I tried to get started with blender python script_Part 01
I tried to touch the CSV file with Python
I tried to draw a route map with Python
I tried to solve the soma cube with python
I tried to get started with blender python script_Part 02
I tried to implement an artificial perceptron with python
I tried to automatically generate a password with Python3
I tried to solve the problem with Python Vol.1
I tried to analyze J League data with Python
I tried to solve AOJ's number theory with Python
I tried to touch Python (installation)
Output to csv file with Python
I tried web scraping with python.
I want to debug with Python
I tried running prolog with python 3.8.2.
I tried SMTP communication with Python
I tried to find the entropy of the image with python
I tried to simulate how the infection spreads with Python
I tried to make various "dummy data" with Python faker
I tried various methods to send Japanese mail with Python
[Python] I tried to visualize tweets about Corona with WordCloud
Mayungo's Python Learning Episode 3: I tried to print numbers with print
I tried to make GUI tic-tac-toe with Python and Tkinter
I tried to divide the file into folders with Python
I tried to summarize Python exception handling
I tried to implement PLSA in Python
I tried to visualize AutoEncoder with TensorFlow
Output color characters to pretty with python
I tried to get started with Hy
I tried to implement PLSA in Python 2
Python3 standard input I tried to summarize
I wanted to solve ABC160 with Python
I tried sending an email with python.
I tried non-photorealistic rendering with Python + opencv
I want to analyze logs with Python
I want to play with aws with python
I tried to implement ADALINE in Python
I tried a functional language with Python
I tried recursion with Python ② (Fibonacci sequence)
I tried to implement PPO in Python
I tried to implement CVAE with PyTorch
I tried to solve TSP with QAOA
[Python] I tried to calculate TF-IDF steadily
I tried to touch Python (basic syntax)
I wanted to solve ABC172 with Python
#I tried something like Vlookup with Python # 2
[5th] I tried to make a certain authenticator-like tool with python
I tried to solve the ant book beginner's edition with python
[2nd] I tried to make a certain authenticator-like tool with python
[3rd] I tried to make a certain authenticator-like tool with python
[Python] A memo that I tried to get started with asyncio
I want to output the beginning of the next month with Python
I tried to create a list of prime numbers with python