Python hat ein Paket namens llvmlite, das sehr nützlich war! LLVM IR kann einfach ausgegeben werden! Ich denke, es ist ein großartiger erster Schritt für LLVM.
Deshalb werde ich versuchen, "llvmlite zu installieren" - "es ein wenig zu versuchen"!
Ich habe Ubuntu unter Windows 7 mit VirtualBox virtualisiert und installiert. Grundsätzlich funktioniert es, wenn es sich um eine von Ubuntu abgeleitete Distribution handelt. Tatsächlich habe ich Linux Mint 17.3 (Cinnamon 64bit) mit dem gleichen Verfahren installiert, aber es funktioniert einwandfrei.
Host
Virtualisierungssoftware
Gastbetriebssystem
Anzahl der Prozessoren
Erinnerung
Wenn es sich nicht um 2 GB handelt, geht LLVM make der Speicher aus.
Bereiten Sie die Erstellung von LLVM und die Vorbereitung der Python 3-Entwicklungsumgebung vor.
$ sudo apt-get install build-essential cmake python3-dev python3-pip python3-setuptools zlib1g-dev libtool
llvmlite erfordert LLVM 3.6. Sie können es mit apt-get erhalten, aber ich möchte das Installationsverzeichnis selbst verwalten, also erstelle ich es selbst.
$ wget http://llvm.org/releases/3.6.2/llvm-3.6.2.src.tar.xz
Ich benutze gerne cmake. Das Erstellen von LLVM dauert eine Weile. Warten Sie also geduldig. (Verwenden Sie make -j4 für den parallelen 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
Machen Sie es auf dem Weg zu 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
#Stellen Sie auch den C-Include-Pfad für alle Fälle ein
export C_INCLUDE_PATH=${LLVM_HOME}/include:${C_INCLUDE_PATH}
export CPLUS_INCLUDE_PATH=${LLVM_HOME}/include:${CPLUS_INCLUDE_PATH}
$ llvm-config --version
3.6.2
Installieren Sie, was Sie wahrscheinlich benötigen. Einige können unnötig sein. Die Python-Bibliothek ist apt-get, pip und es gibt verschiedene Installationsmethoden. Nur scipy und matplotlib konnten nicht mit pip gemacht werden, also habe ich es mit apt-get installiert.
$ sudo -E pip3 install numpy
$ sudo apt-get install python3-scipy python3-matplotlib
$ sudo -E pip3 install pandas statsmodels sympy
Installieren Sie llvmlite schnell mit pip
$ sudo -E pip3 install llvmlite
Das ist es!
Probieren wir es aus! Wenn Sie die folgende Python-Datei ausführen können, funktioniert es!
Unten ist ein Beispiel, das ich entsprechend gemacht habe.
from ctypes import CFUNCTYPE, c_int
import llvmlite.ir as ll
import llvmlite.binding as llvm
"""
Machen Sie dies mit LLVM IR.
def func(x, y):
a = x
b = y
c = 1000
d = a
return a + b + c + d
"""
#Initialisieren
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,Definieren Sie 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)
#Auch speichern
builder.store(a, ptr_d)
#Hinzufügen und zurückgeben
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))
== 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
Betrachtet man LLVM IR (opt). Sie können sehen, dass es kein nutzloses Teil wie Geschäft gibt.
example Es gibt auch ein Beispiel für den ursprünglichen Github, auf den Sie sich beziehen können. https://github.com/numba/llvmlite
Die LLVM-Kopffamilie hat ein Tutorial namens Kaleidoskop. Das Folgende ist eine Implementierung mit llvmlite, was sehr hilfreich ist, daher werde ich es vorstellen.
https://github.com/eliben/pykaleidoscope
Recommended Posts