Difference between revisions of "LLVM"

From YobiWiki
Jump to navigation Jump to search
m
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
=LLVM=
 
=LLVM=
  +
==3.2==
  +
Tagged version on git failed, so working from the tarballs:
  +
<br>Install:
  +
<source lang=bash>
  +
cd /path/to
  +
mkdir llvm32
  +
cd llvm32
  +
wget http://llvm.org/releases/3.2/llvm-3.2.src.tar.gz
  +
wget http://llvm.org/releases/3.2/clang-3.2.src.tar.gz
  +
tar xzf llvm-3.2.src.tar.gz
  +
cd llvm-3.2.src/tools/
  +
tar xzf ../../clang-3.2.src.tar.gz
  +
cd /path/to/llvm32
  +
mkdir llvm-build
  +
cd llvm-build
  +
../llvm-3.2.src/configure --enable-optimized --prefix=/path/to/llvm32/llvm-install
  +
REQUIRES_RTTI=1 make -j3
  +
make install
  +
</source>
  +
Use:
  +
<source lang=bash>
  +
export PATH=/path/to/llvm32/llvm-install/bin:$PATH
  +
</source>
  +
==3.3==
  +
Tagged version on git failed, so working from the tarballs:
  +
<br>Install:
  +
<source lang=bash>
  +
cd /path/to
  +
mkdir llvm33
  +
cd llvm33
  +
wget http://llvm.org/releases/3.3/llvm-3.3.src.tar.gz
  +
wget http://llvm.org/releases/3.3/cfe-3.3.src.tar.gz
  +
tar xzf llvm-3.3.src.tar.gz
  +
cd llvm-3.3.src/tools/
  +
tar xzf ../../cfe-3.3.src.tar.gz
  +
mv cfe-3.3.src clang
  +
cd /path/to/llvm33
  +
mkdir llvm-build
  +
cd llvm-build
  +
../llvm-3.3.src/configure --enable-optimized --prefix=/path/to/llvm33/llvm-install
  +
REQUIRES_RTTI=1 make -j3
  +
make install
  +
</source>
  +
Use:
  +
<source lang=bash>
  +
export PATH=/path/to/llvm33/llvm-install/bin:$PATH
  +
</source>
  +
==3.4==
  +
Install:
  +
<source lang=bash>
  +
cd /path/to
  +
mkdir llvm34
  +
cd llvm34
  +
wget http://llvm.org/releases/3.4/llvm-3.4.src.tar.gz
  +
wget http://llvm.org/releases/3.4/clang-3.4.src.tar.gz
  +
tar xzf llvm-3.4.src.tar.gz
  +
cd llvm-3.4/tools/
  +
tar xzf ../../clang-3.4.src.tar.gz
  +
mv clang-3.4 clang
  +
cd /path/to/llvm34
  +
mkdir llvm-build
  +
cd llvm-build
  +
../llvm-3.4/configure --enable-optimized --prefix=/path/to/llvm34/llvm-install
  +
REQUIRES_RTTI=1 make -j3
  +
make install
  +
</source>
  +
Use:
  +
<source lang=bash>
  +
export PATH=/path/to/llvm34/llvm-install/bin:$PATH
  +
</source>
  +
=LLVM basics=
  +
==src2ir==
  +
clang -Os -S -emit-llvm foo.c -o foo.ll
  +
==src2bc==
  +
clang -Os -c -emit-llvm foo.c -o foo.bc
  +
==ir2bc==
  +
clang -Os -c -emit-llvm foo.ll -o foo.bc
  +
==bc2ir==
  +
llvm-dis -f foo.bc
  +
==bc2bin==
  +
llc foo.bc
  +
==bc analysis==
  +
opt -stats -instcount foo.bc
  +
  +
llvm-bcanalyzer [-dump] foo.bc
  +
See also [http://www.nightmare.com/rushing/python/bc.py bc.py] for another bc parser written in Python
  +
 
=with Python=
 
=with Python=
 
==[http://www.llvmpy.org/ llvmpy]==
 
==[http://www.llvmpy.org/ llvmpy]==
  +
Install with LLVM 3.2:
 
<source lang=bash>
 
<source lang=bash>
  +
export PATH=/path/to/llvm32/llvm-install/bin:$PATH
virtualenv llvmpy.env
 
  +
virtualenv llvmpy_llvm32.env
. llvmpy.env/bin/activate
 
  +
. llvmpy_llvm32.env/bin/activate
 
git clone git@github.com:llvmpy/llvmpy.git llvmpy.git
 
git clone git@github.com:llvmpy/llvmpy.git llvmpy.git
 
cd llvmpy.git
 
cd llvmpy.git
 
git checkout 0.12.5
 
git checkout 0.12.5
LLVM_CONFIG_PATH=/path/to/llvm-install/bin/llvm-config python setup.py install
+
LLVM_CONFIG_PATH=/path/to/llvm32/llvm-install/bin/llvm-config python setup.py install
 
cd ..
 
cd ..
 
python -c "import llvm; llvm.test()"
 
python -c "import llvm; llvm.test()"
  +
deactivate
 
</source>
 
</source>
  +
Usage with LLVM 3.2:
  +
<source lang=bash>
  +
export PATH=/path/to/llvm32/llvm-install/bin:$PATH
  +
. llvmpy_llvm32.env/bin/activate
  +
# Do your stuff... python -c "import llvm; llvm.test()"
  +
deactivate
  +
</source>
  +
  +
Install with LLVM 3.3:
  +
<br>idem, just replace llvm32 by llvm33
  +
  +
Install with LLVM 3.4
  +
<br>v0.12.5 doesn't support LLVM 3.4 apparently, compil fails
  +
 
===[http://www.llvmpy.org/llvmpy-doc/0.12.4/doc/llvm_cbuilder.html llvm_cbuilder]===
 
===[http://www.llvmpy.org/llvmpy-doc/0.12.4/doc/llvm_cbuilder.html llvm_cbuilder]===
 
set of Python-contexts you can use to write C-like constructs in Python which generates llvmpy code directly.
 
set of Python-contexts you can use to write C-like constructs in Python which generates llvmpy code directly.
Line 25: Line 129:
 
''We developed LLPython with the initial goal of simplifying writing LLVM code.''
 
''We developed LLPython with the initial goal of simplifying writing LLVM code.''
   
  +
Tests as at the moment there is very little user doc:
'''TODO''' not clear yet from the doc how to use it...
 
  +
<source lang=python>
  +
import llvm.core as lc
  +
from llpython import bytetype
  +
  +
ll_ipow = lc.Type.function(bytetype.li32, (bytetype.li32, bytetype.li32))
  +
  +
def ipow (val, exp):
  +
ret_val = 1
  +
temp = val
  +
w = exp
  +
while w > 0:
  +
if (w & 1) != 0:
  +
ret_val *= temp
  +
# TODO: Overflow check on ret_val
  +
w >>= 1
  +
if w == 0: break
  +
temp *= temp
  +
# TODO: Overflow check on temp
  +
return ret_val
  +
  +
ll_pymod = lc.Type.function(bytetype.li32, (bytetype.li32, bytetype.li32))
  +
  +
def pymod (arg1, arg2):
  +
ret_val = arg1 % arg2
  +
if ret_val < 0:
  +
if arg2 > 0:
  +
ret_val += arg2
  +
elif arg2 < 0:
  +
ret_val += arg2
  +
return ret_val
  +
  +
lm = lc.Module.new('test_module')
  +
from llpython import byte_translator
  +
byte_translator.translate_function(ipow, ll_ipow, lm)
  +
byte_translator.translate_function(pymod, ll_pymod, lm)
  +
print(lm)
  +
  +
# Ok let's JIT & run the LLVM IR code:
  +
from llvm.ee import ExecutionEngine, GenericValue
  +
ee = ExecutionEngine.new(lm)
  +
  +
arg1 = GenericValue.int(bytetype.li32, 235)
  +
arg2 = GenericValue.int(bytetype.li32, 17)
  +
retval = ee.run_function(lm.get_function_named('pymod'), [arg1, arg2])
  +
print "pymod(235, 17) =", retval.as_int()
  +
  +
# Tried ipow() but it loops infinitely
  +
#arg1 = GenericValue.int(bytetype.li32, 2)
  +
#arg2 = GenericValue.int(bytetype.li32, 8)
  +
#retval = ee.run_function(lm.get_function_named('ipow'), [arg1, arg2])
  +
#print "returned", retval.as_int()
  +
</source>
  +
 
==Numba==
 
==Numba==
 
Numba is a NumPy aware dynamic compiler for Python. It creates LLVM bit-code from Python syntax and then creates a wrapper around that bitcode to call from Python.
 
Numba is a NumPy aware dynamic compiler for Python. It creates LLVM bit-code from Python syntax and then creates a wrapper around that bitcode to call from Python.
Line 42: Line 199:
 
export('multc c16(c16, c16)'))(mult)
 
export('multc c16(c16, c16)'))(mult)
 
</source>
 
</source>
  +
==[https://github.com/numba/llvmlite LLVMlite]==
  +
llvmlite is the lightweight Python binding developed for Numba
  +
 
==Pyston==
 
==Pyston==
 
by Dropbox
 
by Dropbox

Latest revision as of 16:01, 14 November 2014

LLVM

3.2

Tagged version on git failed, so working from the tarballs:
Install:

cd /path/to
mkdir llvm32
cd llvm32
wget http://llvm.org/releases/3.2/llvm-3.2.src.tar.gz
wget http://llvm.org/releases/3.2/clang-3.2.src.tar.gz
tar xzf llvm-3.2.src.tar.gz
cd llvm-3.2.src/tools/
tar xzf ../../clang-3.2.src.tar.gz
cd /path/to/llvm32
mkdir llvm-build
cd llvm-build
../llvm-3.2.src/configure --enable-optimized --prefix=/path/to/llvm32/llvm-install
REQUIRES_RTTI=1 make -j3
make install

Use:

export PATH=/path/to/llvm32/llvm-install/bin:$PATH

3.3

Tagged version on git failed, so working from the tarballs:
Install:

cd /path/to
mkdir llvm33
cd llvm33
wget http://llvm.org/releases/3.3/llvm-3.3.src.tar.gz
wget http://llvm.org/releases/3.3/cfe-3.3.src.tar.gz
tar xzf llvm-3.3.src.tar.gz
cd llvm-3.3.src/tools/
tar xzf ../../cfe-3.3.src.tar.gz
mv cfe-3.3.src clang
cd /path/to/llvm33
mkdir llvm-build
cd llvm-build
../llvm-3.3.src/configure --enable-optimized --prefix=/path/to/llvm33/llvm-install
REQUIRES_RTTI=1 make -j3
make install

Use:

export PATH=/path/to/llvm33/llvm-install/bin:$PATH

3.4

Install:

cd /path/to
mkdir llvm34
cd llvm34
wget http://llvm.org/releases/3.4/llvm-3.4.src.tar.gz
wget http://llvm.org/releases/3.4/clang-3.4.src.tar.gz
tar xzf llvm-3.4.src.tar.gz
cd llvm-3.4/tools/
tar xzf ../../clang-3.4.src.tar.gz
mv clang-3.4 clang
cd /path/to/llvm34
mkdir llvm-build
cd llvm-build
../llvm-3.4/configure --enable-optimized --prefix=/path/to/llvm34/llvm-install
REQUIRES_RTTI=1 make -j3
make install

Use:

export PATH=/path/to/llvm34/llvm-install/bin:$PATH

LLVM basics

src2ir

clang -Os -S -emit-llvm foo.c -o foo.ll

src2bc

clang -Os -c -emit-llvm foo.c -o foo.bc

ir2bc

clang -Os -c -emit-llvm foo.ll -o foo.bc

bc2ir

llvm-dis -f foo.bc

bc2bin

llc foo.bc

bc analysis

opt -stats  -instcount  foo.bc
llvm-bcanalyzer [-dump] foo.bc

See also bc.py for another bc parser written in Python

with Python

llvmpy

Install with LLVM 3.2:

export PATH=/path/to/llvm32/llvm-install/bin:$PATH
virtualenv llvmpy_llvm32.env
. llvmpy_llvm32.env/bin/activate
git clone git@github.com:llvmpy/llvmpy.git llvmpy.git
cd llvmpy.git
git checkout 0.12.5
LLVM_CONFIG_PATH=/path/to/llvm32/llvm-install/bin/llvm-config python setup.py install
cd ..
python -c "import llvm; llvm.test()"
deactivate

Usage with LLVM 3.2:

export PATH=/path/to/llvm32/llvm-install/bin:$PATH
. llvmpy_llvm32.env/bin/activate
# Do your stuff... python -c "import llvm; llvm.test()"
deactivate

Install with LLVM 3.3:
idem, just replace llvm32 by llvm33

Install with LLVM 3.4
v0.12.5 doesn't support LLVM 3.4 apparently, compil fails

llvm_cbuilder

set of Python-contexts you can use to write C-like constructs in Python which generates llvmpy code directly.
Similar to llpython it allows you to build llvm IR without using the llvmpy interface directly.

llpython

The primary goal of the llpython package is to provide a Python dialect/subset that maps directly to LLVM code.
LLPython differs from its originating LLVM translator, Numba, in the following aspects:

  • LLPython code is not intended to work in Python if not translated and wrapped.
  • The LLPython translator only uses LLVM types.
  • LLPython is explicitly typed, and does not support type inference. LLPython does not support implicit casts, all casts must be explicit.
  • LLPython supports code that directly calls the C API, the Python C API, and the llvm.core.Builder methods.

We developed LLPython with the initial goal of simplifying writing LLVM code.

Tests as at the moment there is very little user doc:

import llvm.core as lc
from llpython import bytetype

ll_ipow = lc.Type.function(bytetype.li32, (bytetype.li32, bytetype.li32))

def ipow (val, exp):
    ret_val = 1
    temp = val
    w = exp
    while w > 0:
        if (w & 1) != 0:
            ret_val *= temp
            # TODO: Overflow check on ret_val
        w >>= 1
        if w == 0: break
        temp *= temp
        # TODO: Overflow check on temp
    return ret_val

ll_pymod = lc.Type.function(bytetype.li32, (bytetype.li32, bytetype.li32))

def pymod (arg1, arg2):
    ret_val = arg1 % arg2
    if ret_val < 0:
        if arg2 > 0:
            ret_val += arg2
    elif arg2 < 0:
        ret_val += arg2
    return ret_val

lm = lc.Module.new('test_module')
from llpython import byte_translator
byte_translator.translate_function(ipow, ll_ipow, lm)
byte_translator.translate_function(pymod, ll_pymod, lm)
print(lm)

# Ok let's JIT & run the LLVM IR code:
from llvm.ee import ExecutionEngine, GenericValue
ee = ExecutionEngine.new(lm)

arg1 = GenericValue.int(bytetype.li32, 235)
arg2 = GenericValue.int(bytetype.li32, 17)
retval = ee.run_function(lm.get_function_named('pymod'), [arg1, arg2])
print "pymod(235, 17) =", retval.as_int()

# Tried ipow() but it loops infinitely
#arg1 = GenericValue.int(bytetype.li32, 2)
#arg2 = GenericValue.int(bytetype.li32, 8)
#retval = ee.run_function(lm.get_function_named('ipow'), [arg1, arg2])
#print "returned", retval.as_int()

Numba

Numba is a NumPy aware dynamic compiler for Python. It creates LLVM bit-code from Python syntax and then creates a wrapper around that bitcode to call from Python.

pycc allows users to compile Numba functions into a shared library. The user writes the functions, exports them and the compiler will import the module, collect the exported functions and compile them to a shared library. Below is an example:

from numba import *
def mult(a, b):
    return a * b
export('mult f8(f8, f8)'))(mult)
export(['multf f4(f4, f4)', 'multi i4(i4, i4)'])(mult)
export('multc c16(c16, c16)'))(mult)

LLVMlite

llvmlite is the lightweight Python binding developed for Numba

Pyston

by Dropbox

Not mature yet

old attempts