DOC: Add first version of updated documentation.

This commit is contained in:
Travis E. Oliphant 2012-08-09 13:53:21 -05:00
commit 415c01f745
19 changed files with 474 additions and 595 deletions

View file

@ -1,203 +1,12 @@
+--------------------------------------+
| layout: page |
+--------------------------------------+
| title: Examples and LLVM Tutorials |
+--------------------------------------+
********************************
Examples and LLVM Tutorials
********************************
- This will become a table of contents (this text will be scraped).
{:toc}
.. toctree::
:maxdepth: 1
Examples
========
firstexample.rst
examples/index.rst
kaleidoscope/index.rst
A Simple Function
-----------------
Let's create a (LLVM) module containing a single function, corresponding
to the ``C`` function:
{% highlight c %} int sum(int a, int b) { return a + b; } {%
endhighlight %}
Here's how it looks like:
{% highlight python %} #!/usr/bin/env python
Import the llvmpy modules.
===========================
from llvm import \* from llvm.core import \*
Create an (empty) module.
=========================
my\_module = Module.new('my\_module')
All the types involved here are "int"s. This type is represented
================================================================
by an object of the llvm.core.Type class:
=========================================
ty\_int = Type.int() # by default 32 bits
We need to represent the class of functions that accept two integers
====================================================================
and return an integer. This is represented by an object of the
==============================================================
function type (llvm.core.FunctionType):
=======================================
ty\_func = Type.function(ty\_int, [ty\_int, ty\_int])
Now we need a function named 'sum' of this type. Functions are not
==================================================================
free-standing (in llvmpy); it needs to be contained in a module.
=================================================================
f\_sum = my\_module.add\_function(ty\_func, "sum")
Let's name the function arguments as 'a' and 'b'.
=================================================
f\_sum.args[0].name = "a" f\_sum.args[1].name = "b"
Our function needs a "basic block" -- a set of instructions that
================================================================
end with a terminator (like return, branch etc.). By convention
===============================================================
the first block is called "entry".
==================================
bb = f\_sum.append\_basic\_block("entry")
Let's add instructions into the block. For this, we need an
===========================================================
instruction builder:
====================
builder = Builder.new(bb)
OK, now for the instructions themselves. We'll create an add
============================================================
instruction that returns the sum as a value, which we'll use
============================================================
a ret instruction to return.
============================
tmp = builder.add(f\_sum.args[0], f\_sum.args[1], "tmp")
builder.ret(tmp)
We've completed the definition now! Let's see the LLVM assembly
===============================================================
language representation of what we've created:
==============================================
print my\_module {% endhighlight %}
Here is the output:
{% highlight llvm %} ; ModuleID = 'my\_module'
define i32 @sum(i32 %a, i32 %b) { entry: %tmp = add i32 %a, %b ;
[#uses=1] ret i32 %tmp } {% endhighlight %}
Adding JIT Compilation
----------------------
Let's compile this function in-memory and run it.
{% highlight python %} #!/usr/bin/env python
Import the llvmpy modules.
===========================
from llvm import \* from llvm.core import \* from llvm.ee import \* #
new import: ee = Execution Engine
Create a module, as in the previous example.
============================================
my\_module = Module.new('my\_module') ty\_int = Type.int() # by default
32 bits ty\_func = Type.function(ty\_int, [ty\_int, ty\_int]) f\_sum =
my\_module.add\_function(ty\_func, "sum") f\_sum.args[0].name = "a"
f\_sum.args[1].name = "b" bb = f\_sum.append\_basic\_block("entry")
builder = Builder.new(bb) tmp = builder.add(f\_sum.args[0],
f\_sum.args[1], "tmp") builder.ret(tmp)
Create an execution engine object. This will create a JIT compiler
==================================================================
on platforms that support it, or an interpreter otherwise.
==========================================================
ee = ExecutionEngine.new(my\_module)
The arguments needs to be passed as "GenericValue" objects.
===========================================================
arg1 = GenericValue.int(ty\_int, 100) arg2 = GenericValue.int(ty\_int,
42)
Now let's compile and run!
==========================
retval = ee.run\_function(f\_sum, [arg1, arg2])
The return value is also GenericValue. Let's print it.
======================================================
print "returned", retval.as\_int() {% endhighlight %}
And here's the output:
::
returned 142
--------------
LLVM Tutorials
==============
Simple JIT Tutorials
--------------------
The following JIT tutorials were contributed by Sebastien Binet.
1. `A First Function <examples/JITTutorial1.html>`_
2. `A More Complicated Function <examples/JITTutorial2.html>`_
Kaleidoscope ## {#kaleidoscope}
-------------------------------
Implementing a Language with LLVM
The LLVM `Kaleidoscope <http://www.llvm.org/docs/tutorial/>`_ tutorial
has been ported to llvmpy by Max Shawabkeh.
1. `Tutorial Introduction and the
Lexer <kaleidoscope/PythonLangImpl1.html>`_
2. `Implementing a Parser and AST <kaleidoscope/PythonLangImpl2.html>`_
3. `Implementing Code Generation to LLVM
IR <kaleidoscope/PythonLangImpl3.html>`_
4. `Adding JIT and Optimizer
Support <kaleidoscope/PythonLangImpl4.html>`_
5. `Extending the language: control
flow <kaleidoscope/PythonLangImpl5.html>`_
6. `Extending the language: user-defined
operators <kaleidoscope/PythonLangImpl6.html>`_
7. `Extending the language: mutable variables / SSA
construction <kaleidoscope/PythonLangImpl7.html>`_
8. `Conclusion and other useful LLVM
tidbits <kaleidoscope/PythonLangImpl8.html>`_

View file

@ -1,45 +1,36 @@
+-------------------------+
| layout: page |
+-------------------------+
| title: JIT Tutorial 1 |
+-------------------------+
A First Function
==================
{% highlight python %} #!/usr/bin/env python
.. code-block:: python
from llvm.core import \*
#!/usr/bin/env python
from llvm.core import *
create a module
===============
#create a module
module = Module.new("tut1")
module = Module.new ("tut1")
#create a function type taking 3 32-bit integers, return a 32-bit integer
ty_int = Type.int(32)
func_type = Type.function(ty_int, (ty_int,)*3)
create a function type taking 3 32-bit integers, return a 32-bit integer
========================================================================
#create a function of that type
mul_add = Function.new (module, func_type, "mul_add")
mul_add.calling_convention = CC_C
x = mul_add.args[0]; x.name = "x"
y = mul_add.args[1]; y.name = "y"
z = mul_add.args[2]; z.name = "z"
ty\_int = Type.int (32) func\_type = Type.function (ty\_int,
(ty\_int,)\*3)
#implement the function
create a function of that type
==============================
#new block
blk = mul_add.append_basic_block("entry")
mul\_add = Function.new (module, func\_type, "mul\_add")
mul\_add.calling\_convention = CC\_C x = mul\_add.args[0]; x.name = "x"
y = mul\_add.args[1]; y.name = "y" z = mul\_add.args[2]; z.name = "z"
#IR builder
bldr = Builder.new(blk)
tmp_1 = bldr.mul(x, y, "tmp_1")
tmp_2 = bldr.add(tmp_1, z, "tmp_2")
implement the function
======================
bldr.ret(tmp_2)
new block
=========
blk = mul\_add.append\_basic\_block ("entry")
IR builder
==========
bldr = Builder.new (blk) tmp\_1 = bldr.mul (x, y, "tmp\_1") tmp\_2 =
bldr.add (tmp\_1, z, "tmp\_2")
bldr.ret (tmp\_2)
print(module) {% endhighlight %}
print module

View file

@ -1,62 +1,55 @@
+-------------------------+
| layout: page |
+-------------------------+
| title: JIT Tutorial 2 |
+-------------------------+
A More Complicated Function
====================
{% highlight python %} #!/usr/bin/env python
.. code-block:: python
from llvm.core import \*
#!/usr/bin/env python
create a module
===============
from llvm.core import *
module = Module.new ("tut2")
#create a module
module = Module.new("tut2")
create a function type taking 2 integers, return a 32-bit integer
=================================================================
#create a function type taking 2 integers, return a 32-bit integer
ty_int = Type.int(32)
func_type = Type.function(ty_int, (ty_int, ty_int))
ty\_int = Type.int (32) func\_type = Type.function (ty\_int, (ty\_int,
ty\_int))
#create a function of that type
gcd = Function.new(module, func_type, "gcd")
create a function of that type
==============================
#name function args
x = gcd.args[0]; x.name = "x"
y = gcd.args[1]; y.name = "y"
gcd = Function.new (module, func\_type, "gcd")
#implement the function
name function args
==================
#blocks...
entry = gcd.append_basic_block("entry")
ret = gcd.append_basic_block("return")
cond_false = gcd.append_basic_block("cond_false")
cond_true = gcd.append_basic_block("cond_true")
cond_false_2 = gcd.append_basic_block("cond_false_2")
x = gcd.args[0]; x.name = "x" y = gcd.args[1]; y.name = "y"
#create a llvm::IRBuilder
bldr = Builder.new(entry)
x_eq_y = bldr.icmp(IPRED_EQ, x, y, "tmp")
bldr.cbranch(x_eq_y, ret, cond_false)
implement the function
======================
bldr.position_at_end (ret)
bldr.ret(x)
blocks...
=========
bldr.position_at_end(cond_false)
x_lt_y = bldr.icmp(IPRED_ULT, x, y, "tmp")
bldr.cbranch(x_lt_y, cond_true, cond_false_2)
entry = gcd.append\_basic\_block ("entry") ret =
gcd.append\_basic\_block ("return") cond\_false =
gcd.append\_basic\_block ("cond\_false") cond\_true =
gcd.append\_basic\_block ("cond\_true") cond\_false\_2 =
gcd.append\_basic\_block ("cond\_false\_2")
bldr.position_at_end(cond_true)
y_sub_x = bldr.sub(y, x, "tmp")
recur_1 = bldr.call(gcd, (x, y_sub_x,), "tmp")
bldr.ret(recur_1)
create a llvm::IRBuilder
========================
bldr.position_at_end(cond_false_2)
x_sub_y = bldr.sub(x, y, "x_sub_y")
recur_2 = bldr.call(gcd, (x_sub_y, y,), "tmp")
bldr.ret(recur_2)
bldr = Builder.new (entry) x\_eq\_y = bldr.icmp (IPRED\_EQ, x, y, "tmp")
bldr.cbranch (x\_eq\_y, ret, cond\_false)
bldr.position\_at\_end (ret) bldr.ret(x)
bldr.position\_at\_end (cond\_false) x\_lt\_y = bldr.icmp (IPRED\_ULT,
x, y, "tmp") bldr.cbranch (x\_lt\_y, cond\_true, cond\_false\_2)
bldr.position\_at\_end (cond\_true) y\_sub\_x = bldr.sub (y, x, "tmp")
recur\_1 = bldr.call (gcd, (x, y\_sub\_x,), "tmp") bldr.ret (recur\_1)
bldr.position\_at\_end (cond\_false\_2) x\_sub\_y = bldr.sub (x, y,
"x\_sub\_y") recur\_2 = bldr.call (gcd, (x\_sub\_y, y,), "tmp") bldr.ret
(recur\_2)
print(module) {% endhighlight %}
print module

View file

@ -0,0 +1,10 @@
LLVM Tutorials
==============
The following JIT tutorials were contributed by Sebastien Binet.
.. toctree::
:titlesonly:
JITTutorial1.rst
JITTutorial2.rst

View file

@ -0,0 +1,125 @@
Examples
========
A Simple Function
-----------------
Let's create a (LLVM) module containing a single function, corresponding
to the ``C`` function:
.. code-block:: c
int sum(int a, int b)
{
return a + b;
}
Here's how it looks in llvmpy:
.. code-block:: python
#!/usr/bin/env python
# Import the llvmpy modules.
from llvm import *
from llvm.core import *
# Create an (empty) module.
my_module = Module.new('my_module')
# All the types involved here are "int"s. This type is represented
# by an object of the llvm.core.Type class:
ty_int = Type.int() # by default 32 bits
# We need to represent the class of functions that accept two integers
# and return an integer. This is represented by an object of the
# function type (llvm.core.FunctionType):
ty_func = Type.function(ty_int, [ty_int, ty_int])
# Now we need a function named 'sum' of this type. Functions are not
# free-standing (in llvmpy); it needs to be contained in a module.
f_sum = my_module.add_function(ty_func, "sum")
# Let's name the function arguments as 'a' and 'b'.
f_sum.args[0].name = "a"
f_sum.args[1].name = "b"
# Our function needs a "basic block" -- a set of instructions that
# end with a terminator (like return, branch etc.). By convention
# the first block is called "entry".
bb = f_sum.append_basic_block("entry")
# Let's add instructions into the block. For this, we need an
# instruction builder:
builder = Builder.new(bb)
# OK, now for the instructions themselves. We'll create an add
# instruction that returns the sum as a value, which we'll use
# a ret instruction to return.
tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
builder.ret(tmp)
# We've completed the definition now! Let's see the LLVM assembly
# language representation of what we've created:
print my_module
Here is the output:
.. code-block:: llvm
; ModuleID = 'my_module'
define i32 @sum(i32 %a, i32 %b) {
entry:
%tmp = add i32 %a, %b ; <i32> [#uses=1]
ret i32 %tmp
}
Adding JIT Compilation
----------------------
Let's compile this function in-memory and run it.
.. code-block:: python
#!/usr/bin/env python
# Import the llvmpy modules.
from llvm import *
from llvm.core import *
from llvm.ee import * # new import: ee = Execution Engine
#Create a module, as in the previous example.
my_module = Module.new('my_module')
ty_int = Type.int() # by default 32 bits
ty_func = Type.function(ty_int, [ty_int, ty_int])
f_sum = my_module.add_function(ty_func, "sum")
f_sum.args[0].name = "a"
f_sum.args[1].name = "b"
bb = f_sum.append_basic_block("entry")
builder = Builder.new(bb)
tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
builder.ret(tmp)
# Create an execution engine object. This will create a JIT compiler
# on platforms that support it, or an interpreter otherwise.
ee = ExecutionEngine.new(my_module)
# The arguments needs to be passed as "GenericValue" objects.
arg1 = GenericValue.int(ty_int, 100)
arg2 = GenericValue.int(ty_int, 42)
# Now let's compile and run!
retval = ee.run_function(f_sum, [arg1, arg2])
# The return value is also GenericValue. Let's print it.
print "returned", retval.as_int()
And here's the output:
::
returned 142

View file

@ -0,0 +1,153 @@
Introduction
============
`LLVM <http://www.llvm.org/>`_ (Low-Level Virtual Machine) provides
enough infrastructure to use it as the backend for your compiled, or
JIT-compiled language. It provides extensive optimization support, and
static and dynamic (JIT) backends for many platforms. See the website at
http://www.llvm.org/ to discover more.
Python bindings for LLVM provides a gentler learning curve for working
with the LLVM APIs. It should also be easier to create working
prototypes and experimental languages using this medium.
Together with `clang <http://clang.llvm.org/>`_ or
`llvm-gcc <http://llvm.org/cmds/llvmgcc.html>`_ it also a provides a
means to quickly instrument C and C++ sources. For e.g., llvm-gcc can be
used to generate the LLVM assembly for a given C source file, which can
then be loaded and manipulated (adding profiling code to every function,
say) using a llvmpy based Python script.
License
-------
Both LLVM and llvmpy are distributed under (different) permissive open
source licenses. llvmpy uses the `new BSD
license <http://opensource.org/licenses/bsd-license.php>`_. More
information is available
`here <https://github.com/numba/llvmpy/blob/master/LICENSE>`_.
Platforms
---------
llvmpy has been built/tested/reported to work on various GNU/Linux
flavours, BSD, Mac OS X; on i386 and amd64 architectures. Windows is not
supported, for a variety of reasons.
Versions
--------
llvmpy 0.8.2 requires version 3.1 of LLVM. It may not work with
previous versions.
llvmpy has been built and tested with Python 2.7. It should work with
earlier versions. It has not been tried with Python 3.x (patches
welcome).
Installation
============
The Git repo of llvmpy is at https://github.com/numba/llvmpy.git.
You'll need to build and install it before it can be used. At least the
following will be required for this:
- C and C++ compilers (gcc/g++)
- Python itself
- Python development files (headers and libraries)
- LLVM, either installed or built
On debian-based systems, the first three can be installed with the
command ``sudo apt-get install gcc g++ python python-dev``. Ensure that
your distro's repository has the appropriate version of LLVM!
It does not matter which compiler LLVM itself was built with (``g++``,
``llvm-g++`` or any other); llvmpy can be built with any compiler. It
has been tried only with gcc/g++ though.
LLVM and ``--enable-pic``
-------------------------
The result of an LLVM build is a set of static libraries and object
files. The llvmpy contains an extension package that is built into a
shared object (\_core.so) which links to these static libraries and
object files. It is therefore required that the LLVM libraries and
object files be built with the ``-fPIC`` option (generate position
independent code). Be sure to use the ``--enable-pic`` option while
configuring LLVM (default is no PIC), like this:
{% highlight bash %} ~/llvm$ ./configure --enable-pic --enable-optimized
{% endhighlight %}
llvm-config
-----------
In order to build llvmpy, it's build script needs to know from where it
can invoke the llvm helper program, ``llvm-config``. If you've installed
LLVM, then this will be available in your ``PATH``, and nothing further
needs to be done. If you've built LLVM yourself, or for any reason
``llvm-config`` is not in your ``PATH``, you'll need to pass the full
path of ``llvm-config`` to the build script.
You'll need to be 'root' to install llvmpy. Remember that your ``PATH``
is different from that of 'root', so even if ``llvm-config`` is in your
``PATH``, it may not be available when you do ``sudo``.
Steps
-----
Get 3.1 version of LLVM, build it. Make sure '--enable-pic' is passed to
LLVM's 'configure'.
Get llvmpy and install it:
{% highlight bash %} $ git clone git@github.com:numba/llvmpy.git $ cd
llvmpy $ python setup.py install {% endhighlight %}
If you need to tell the build script where ``llvm-config`` is, do it
this way:
{% highlight bash %} $ python setup.py install --user
--llvm-config=/home/mdevan/llvm/Release/bin/llvm-config {% endhighlight
%}
To build a debug version of llvmpy, that links against the debug
libraries of LLVM, use this:
{% highlight bash %} $ python setup.py build -g
--llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config $ python setup.py
install --user --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config {%
endhighlight %}
Be warned that debug binaries will be huge (100MB+) ! They are required
only if you need to debug into LLVM also.
``setup.py`` is a standard Python distutils script. See the Python
documentation regarding `Installing Python
Modules <http://docs.python.org/inst/inst.html>`_ and `Distributing
Python Modules <http://docs.python.org/dist/dist.html>`_ for more
information on such scripts.
Uninstall
==============
If you'd installed llvmpy with the ``--user`` option, then llvmpy
would be present under ``~/.local/lib/python2.7/site-packages``.
Otherwise, it might be under ``/usr/lib/python2.7/site-packages`` or
``/usr/local/lib/python2.7/site-packages``. The directory would vary
with your Python version and OS flavour. Look around.
Once you've located the site-packages directory, the modules and the
"egg" can be removed like so:
{% highlight bash %} $ rm -rf /llvm /llvm\_py-.egg-info {% endhighlight
%}
See the `Python
documentation <http://docs.python.org/install/index.html>`_ for more
information.
--------------

View file

@ -1,24 +1,12 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 1" |
+------------------------------------+
Tutorial Introduction and the Lexer
===================================
*************************************************
Chapter 1: Tutorial Introduction and the Lexer
*************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 1**
- This will become a table of contents (this text will be scraped).
{:toc}
`**Chapter 2: Implementing a Parser and AST** <PythonLangImpl2.html>`_
Introduction
============
=========
Welcome to the "Implementing a language with LLVM" tutorial. This
tutorial runs through the implementation of a simple language, showing

View file

@ -1,22 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 2" |
+------------------------------------+
Implementing a Parser and AST
=============================
***************************************************
Chapter 2: Implementing a Parser and AST
***************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 2**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 3: Code generation to LLVM IR <PythonLangImpl3.html>`_**
Introduction # {#intro}
=======================

View file

@ -1,23 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 3" |
+------------------------------------+
Code generation to LLVM IR
==========================
*******************************************
Chapter 3: Code generation to LLVM IR
*******************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 3**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 4: Adding JIT and Optimizer
Support <PythonLangImpl4.html>`_**
Introduction # {#intro}
=======================
@ -32,7 +19,7 @@ and parser than it is to generate LLVM IR code. :)
**Please note**: the code in this chapter and later requires llvmpy 0.6
and LLVM 2.7. Earlier versions will most likely not work with it. Also
note that you need to use a version of this tutorial that matches your
llvmpy release: If you are using an official llvm-py release, use the
llvmpy release: If you are using an official llvmpy release, use the
version of the documentation on the `llvmpy examples
page <http://www.mdevan.org/llvmpy/examples.html>`_

View file

@ -1,23 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 4" |
+------------------------------------+
Adding JIT and Optimizer Support
================================
*************************************************
Chapter 4: Adding JIT and Optimizer Support
*************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 4**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 5: Extending the Language: Control
Flow <PythonLangImpl5.html>`_**
Introduction # {#intro}
=======================

View file

@ -1,23 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 5" |
+------------------------------------+
Extending the Language: Control Flow
====================================
*****************************************************
Chapter 5: Extending the Language: Control Flow
*****************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 5**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 6: Extending the Language: User-defined
Operators <PythonLangImpl6.html>`_**
Introduction # {#intro}
=======================

View file

@ -1,23 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 6" |
+------------------------------------+
Extending the Language: User-defined Operators
==============================================
**********************************************************************
Chapter 6: Extending the Language: User-defined Operators
**********************************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 6**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 7: Extending the Language: Mutable Variables / SSA
Construction <PythonLangImpl7.html>`_**
Introduction # {#intro}
=======================

View file

@ -1,23 +1,10 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 7" |
+------------------------------------+
Extending the Language: Mutable Variables / SSA construction
============================================================
*******************************************************************************
Chapter 7: Extending the Language: Mutable Variables / SSA construction
*******************************************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_ and `Max
Shawabkeh <http://max99x.com>`_
**Chapter 7**
- This will become a table of contents (this text will be scraped).
{:toc}
**`Chapter 8: Conclusion and other useful LLVM
tidbits <PythonLangImpl8.html>`_**
Introduction # {#intro}
=======================

View file

@ -1,18 +1,9 @@
+------------------------------------+
| layout: page |
+------------------------------------+
| title: "Kaleidoscope: Chapter 8" |
+------------------------------------+
Conclusion and other useful LLVM tidbits
========================================
*****************************************************************
Chapter 8: Conclusion and other useful LLVM tidbits
*****************************************************************
Written by `Chris Lattner <mailto:sabre@nondot.org>`_
**Chapter 8**
- This will become a table of contents (this text will be scraped).
{:toc}
Tutorial Conclusion # {#conclusion}
===================================

View file

@ -0,0 +1,21 @@
Kaleidoscope
--------------
Implementing a Language with LLVM
The LLVM `Kaleidoscope <http://www.llvm.org/docs/tutorial/>`_ tutorial
has been ported to llvmpy by Max Shawabkeh.
.. toctree::
:titlesonly:
:numbered:
PythonLangImpl1.rst
PythonLangImpl2.rst
PythonLangImpl3.rst
PythonLangImpl4.rst
PythonLangImpl5.rst
PythonLangImpl6.rst
PythonLangImpl7.rst
PythonLangImpl8.rst

View file

@ -1,12 +1,16 @@
+------------------------+
| layout: page |
+------------------------+
| title: LLVM Concepts |
+------------------------+
********************
LLVM Concepts
********************
This section explains a few concepts related to LLVM, not specific to
llvmpy.
.. toctree::
:hidden:
Intermediate Representation
===========================
@ -36,7 +40,6 @@ instructions related to variable argument handling, exception handling,
and garbage collection. These allow high-level languages to be
represented cleanly in the IR.
--------------
SSA Form and PHI Nodes
======================
@ -51,15 +54,24 @@ when a variable can be assigned a different value based on the path of
control flow. For example, the value of *b* at the end of execution of
the snippet below:
{% highlight c %} a = 1; if (v < 10) a = 2; b = a; {% endhighlight %}
.. code-block:: c
a = 1;
if (v < 10)
a = 2;
b = a;
cannot be determined statically. The value of '2' cannot be assigned to
the 'original' *a*, since *a* can be assigned to only once. There are
two *a* 's in there, and the last assignment has to choose between which
version to pick. This is accomplished by adding a PHI node:
{% highlight c %} a1 = 1; if (v < 10) a2 = 2; b = PHI(a1, a2); {%
endhighlight %}
.. code-block:: c
a1 = 1;
if (v < 10)
a2 = 2;
b = PHI(a1, a2);
The PHI node selects *a1* or *a2*, depending on where the control
reached the PHI node. The argument *a1* of the PHI node is associated
@ -68,7 +80,6 @@ with the block *"a1 = 1;"* and *a2* with the block *"a2 = 2;"*.
PHI nodes have to be explicitly created in the LLVM IR. Accordingly the
LLVM instruction set has an instruction called *phi*.
--------------
LLVM Assembly Language
======================
@ -90,30 +101,48 @@ language code.
Just to get a feel of the LLVM assembly language, here's a function in
C, and the corresponding LLVM assembly (as generated by the demo page):
{% highlight c %} /\* compute sum of 1..n \*/ unsigned sum(unsigned n) {
if (n == 0) return 0; else return n + sum(n-1); } {% endhighlight %}
.. code-block:: c
/* compute sum of 1..n */
unsigned sum(unsigned n) {
if (n == 0)
return 0;
else
return n + sum(n-1);
}
The corresponding LLVM assembly:
{% highlight llvm %} ; ModuleID = '/tmp/webcompile/\_7149\_0.bc' target
datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86\_64-linux-gnu"
.. code-block:: llvm
define i32 @sum(i32 %n) nounwind readnone { entry: %0 = icmp eq i32 %n,
0 ; [#uses=1] br i1 %0, label %bb2, label %bb1
; ModuleID = '/tmp/webcompile/_7149_0.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-linux-gnu"
bb1: ; preds = %entry %1 = add i32 %n, -1 ; [#uses=2] %2 = icmp eq i32
%1, 0 ; [#uses=1] br i1 %2, label %sum.exit, label %bb1.i
define i32 @sum(i32 %n) nounwind readnone {
entry:
%0 = icmp eq i32 %n, 0 ; [#uses=1]
br i1 %0, label %bb2, label %bb1
bb1.i: ; preds = %bb1 %3 = add i32 %n, -2 ; [#uses=1] %4 = tail call i32
@sum(i32 %3) nounwind ; [#uses=1] %5 = add i32 %4, %1 ; [#uses=1] br
label %sum.exit
bb1: ; preds = %entry
%1 = add i32 %n, -1 ; [#uses=2]
%2 = icmp eq i32 %1, 0 ; [#uses=1]
br i1 %2, label %sum.exit, label %bb1.i
sum.exit: ; preds = %bb1.i, %bb1 %6 = phi i32 [ %5, %bb1.i ], [ 0, %bb1
] ; [#uses=1] %7 = add i32 %6, %n ; [#uses=1] ret i32 %7
bb1.i: ; preds = %bb1
%3 = add i32 %n, -2 ; [#uses=1]
%4 = tail call i32 @sum(i32 %3) nounwind ; [#uses=1]
%5 = add i32 %4, %1 ; [#uses=1]
br label %sum.exit
bb2: ; preds = %entry ret i32 0 } {% endhighlight %}
sum.exit: ; preds = %bb1.i, %bb1
%6 = phi i32 [ %5, %bb1.i ], [ 0, %bb1 ] ; [#uses=1]
%7 = add i32 %6, %n ; [#uses=1]
ret i32 %7
bb2: ; preds = %entry
ret i32 0
}
Note the usage of SSA form. The long string called ``target datalayout``
is a specification of the platform ABI (like endianness, sizes of types,
@ -122,7 +151,6 @@ alignment etc.).
The `LLVM Language Reference <http://www.llvm.org/docs/LangRef.html>`_
defines the LLVM assembly language including the entire instruction set.
--------------
Modules
=======
@ -139,7 +167,6 @@ contained within modules. Modules may be combined (linked) together to
give a bigger resultant module. During this process LLVM attempts to
reconcile the references between the combined modules.
--------------
Optimization and Passes
=======================
@ -184,7 +211,6 @@ LLVM defines two kinds of pass managers:
`PassManager <http://llvm.org/docs/doxygen/html/classllvm_1_1PassManager.html>`_
manages module passes for optimizing the entire module.
--------------
Bitcode
=======
@ -195,7 +221,6 @@ compiler <http://llvm.org/docs/LangRef.html#introduction>`_. See `LLVM
documentation <http://llvm.org/docs/BitCodeFormat.html>`_ for detail
about the bitcode format.
--------------
Execution Engine, JIT and Interpreter
=====================================
@ -209,6 +234,3 @@ multiple modules.
Inter-module reference is not possible. That is module ``A`` cannot
call a function in module ``B``, directly.
--------------
**Next** -- `llvmpy Package <./llvm-py_package.html>`_

View file

@ -1,8 +1,6 @@
+------------------------------+
| layout: page |
+------------------------------+
| title: The llvmpy Package |
+------------------------------+
***********************
The llvmpy Package
***********************
The llvmpy is a Python package, consisting of 6 modules, that wrap over
enough LLVM APIs to allow the implementation of your own compiler/VM

View file

@ -6,158 +6,12 @@ llvmpy provides Python bindings for LLVM. This document explains how
you can setup and use it. A working knowledge of Python and a basic idea
of LLVM is assumed.
Introduction
============
.. toctree::
:maxdepth: 1
`LLVM <http://www.llvm.org/>`_ (Low-Level Virtual Machine) provides
enough infrastructure to use it as the backend for your compiled, or
JIT-compiled language. It provides extensive optimization support, and
static and dynamic (JIT) backends for many platforms. See the website at
http://www.llvm.org/ to discover more.
getting_started.rst
llvm_concepts.rst
llvmpy_package.rst
Python bindings for LLVM provides a gentler learning curve for working
with the LLVM APIs. It should also be easier to create working
prototypes and experimental languages using this medium.
Together with `clang <http://clang.llvm.org/>`_ or
`llvm-gcc <http://llvm.org/cmds/llvmgcc.html>`_ it also a provides a
means to quickly instrument C and C++ sources. For e.g., llvm-gcc can be
used to generate the LLVM assembly for a given C source file, which can
then be loaded and manipulated (adding profiling code to every function,
say) using a llvmpy based Python script.
License
-------
Both LLVM and llvmpy are distributed under (different) permissive open
source licenses. llvmpy uses the `new BSD
license <http://opensource.org/licenses/bsd-license.php>`_. More
information is available
`here <https://github.com/numba/llvmpy/blob/master/LICENSE>`_.
Platforms
---------
llvmpy has been built/tested/reported to work on various GNU/Linux
flavours, BSD, Mac OS X; on i386 and amd64 architectures. Windows is not
supported, for a variety of reasons.
Versions
--------
llvmpy 0.8.2 requires version 3.1 of LLVM. It may not work with
previous versions.
llvmpy has been built and tested with Python 2.7. It should work with
earlier versions. It has not been tried with Python 3.x (patches
welcome).
--------------
Installation
============
The Git repo of llvmpy is at https://github.com/numba/llvmpy.git.
You'll need to build and install it before it can be used. At least the
following will be required for this:
- C and C++ compilers (gcc/g++)
- Python itself
- Python development files (headers and libraries)
- LLVM, either installed or built
On debian-based systems, the first three can be installed with the
command ``sudo apt-get install gcc g++ python python-dev``. Ensure that
your distro's repository has the appropriate version of LLVM!
It does not matter which compiler LLVM itself was built with (``g++``,
``llvm-g++`` or any other); llvmpy can be built with any compiler. It
has been tried only with gcc/g++ though.
LLVM and ``--enable-pic``
-------------------------
The result of an LLVM build is a set of static libraries and object
files. The llvmpy contains an extension package that is built into a
shared object (\_core.so) which links to these static libraries and
object files. It is therefore required that the LLVM libraries and
object files be built with the ``-fPIC`` option (generate position
independent code). Be sure to use the ``--enable-pic`` option while
configuring LLVM (default is no PIC), like this:
{% highlight bash %} ~/llvm$ ./configure --enable-pic --enable-optimized
{% endhighlight %}
llvm-config
-----------
In order to build llvmpy, it's build script needs to know from where it
can invoke the llvm helper program, ``llvm-config``. If you've installed
LLVM, then this will be available in your ``PATH``, and nothing further
needs to be done. If you've built LLVM yourself, or for any reason
``llvm-config`` is not in your ``PATH``, you'll need to pass the full
path of ``llvm-config`` to the build script.
You'll need to be 'root' to install llvmpy. Remember that your ``PATH``
is different from that of 'root', so even if ``llvm-config`` is in your
``PATH``, it may not be available when you do ``sudo``.
Steps
-----
Get 3.1 version of LLVM, build it. Make sure '--enable-pic' is passed to
LLVM's 'configure'.
Get llvmpy and install it:
{% highlight bash %} $ git clone git@github.com:numba/llvmpy.git $ cd
llvmpy $ python setup.py install {% endhighlight %}
If you need to tell the build script where ``llvm-config`` is, do it
this way:
{% highlight bash %} $ python setup.py install --user
--llvm-config=/home/mdevan/llvm/Release/bin/llvm-config {% endhighlight
%}
To build a debug version of llvmpy, that links against the debug
libraries of LLVM, use this:
{% highlight bash %} $ python setup.py build -g
--llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config $ python setup.py
install --user --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config {%
endhighlight %}
Be warned that debug binaries will be huge (100MB+) ! They are required
only if you need to debug into LLVM also.
``setup.py`` is a standard Python distutils script. See the Python
documentation regarding `Installing Python
Modules <http://docs.python.org/inst/inst.html>`_ and `Distributing
Python Modules <http://docs.python.org/dist/dist.html>`_ for more
information on such scripts.
--------------
Uninstall # {#uninstall}
========================
If you'd installed llvmpy with the ``--user`` option, then llvmpy
would be present under ``~/.local/lib/python2.7/site-packages``.
Otherwise, it might be under ``/usr/lib/python2.7/site-packages`` or
``/usr/local/lib/python2.7/site-packages``. The directory would vary
with your Python version and OS flavour. Look around.
Once you've located the site-packages directory, the modules and the
"egg" can be removed like so:
{% highlight bash %} $ rm -rf /llvm /llvm\_py-.egg-info {% endhighlight
%}
See the `Python
documentation <http://docs.python.org/install/index.html>`_ for more
information.
--------------
**Next** -- :doc:`llvm_concepts`