llvmpy/www/web/userguide.html
mdevan.foobar 9cc8fdc0cd Build cleanly with LLVM 2.3 or 2.3svn.
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@15 8d1e9007-1d4e-0410-b67e-1979fd6579aa
2008-06-18 16:31:35 +00:00

1737 lines
70 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.2.2" />
<meta name="description" content="Text based document generation" />
<meta name="keywords" content="text to HTML, text to DocBook, text to XML, AsciiDoc" />
<link rel="stylesheet" href="style/xhtml11.css" type="text/css" />
<link rel="stylesheet" href="style/xhtml11-quirks.css" type="text/css" />
<link rel="stylesheet" href="style/layout.css" type="text/css" />
<title>llvm-py User Guide - llvm-py</title>
</head>
<body>
<div id="layout-banner">
<div id="layout-title">llvm-py</div>
<div id="layout-description">Python Bindings for LLVM</div>
</div>
<table>
<tr valign="top">
<td id="layout-menu">
<div>&#187;<a href="index.html">Home</a></div>
<div>&#187;<a href="examples.html">Examples</a></div>
<div>&#187;<a href="download.html">Download</a></div>
<div>&#187;<a href="userguide.html">User&nbsp;Guide</a></div>
<div>&#187;<a href="contribute.html">Contribute</a></div>
<div>&#187;<a href="license.html">License</a></div>
<div>&#187;<a href="about.html">About</a></div>
<div id="page-source">&#187;<a href="http://www.python.org/">Python</a></div>
<div>&#187;<a href="http://llvm.org/">LLVM</a></div>
</td>
<td>
<div id="layout-content">
<div id="header">
<h1>llvm-py User Guide</h1>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="admonitionblock">
<table><tr>
<td class="icon">
<img src="./images/icons/note.png" alt="Note" />
</td>
<td class="content">This document is updated constantly. Check back often.</td>
</tr></table>
</div>
<p>llvm-py 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.</p>
</div>
</div>
<h2>Introduction</h2>
<div class="sectionbody">
<p><a href="http://www.llvm.org/">LLVM</a> (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
<a href="http://www.llvm.org/">http://www.llvm.org/</a> to discover more.</p>
<p>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.</p>
<div class="title">License</div>
<p>Both LLVM and llvm-py are distributed under (different) permissive
open source licenses. llvm-py uses the
<a href="http://opensource.org/licenses/bsd-license.php">new BSD license</a>. More
information is available <a href="license.html">here</a>.</p>
<div class="title">Platforms</div>
<p>Currently, llvm-py has been built and tested only on Linux/x86. However,
it should be trivial to build it on other unices. Windows is not
supported, for a variety of reasons.</p>
<div class="title">Versions</div>
<p>llvm-py requires verion 2.3 of LLVM. It will not work with previous
versions.</p>
<p>llvm-py has been built and tested with Python 2.5. It should work with
Python 2.4, with minimal changes, if any.</p>
</div>
<h2><a id="install"></a>Installation</h2>
<div class="sectionbody">
<p>llvm-py is distributed as a source tarball. You'll need to build and
install it before it can be used. At least the following will be
required for this:</p>
<ul>
<li>
<p>
C and C++ compilers (gcc/g++)
</p>
</li>
<li>
<p>
Python itself
</p>
</li>
<li>
<p>
Python development files (headers and libraries)
</p>
</li>
<li>
<p>
LLVM, either installed or built
</p>
</li>
</ul>
<p>On debian-based systems, the first three can be installed with the
command `sudo apt-get install gcc g++ python python-dev'. Note that
ubuntu repository has an old version of llvm (1.8) which will not work
with llvm-py.</p>
<p>It does not matter which compiler LLVM itself was built with (g++,
llvm-g++ or any other); llvm-py can be built with any compiler. It has
been tried only with gcc/g++ though.</p>
<p>Tip: If LLVM 2.3 does not install cleanly, try installing &#8220;ocamldoc&#8221;
first.</p>
<h3>llvm-config</h3>
<p>Inorder to build llvm-py, it's build script needs to know from where to
invoke the llvm helper program, <tt>llvm-config</tt>. If you've installed LLVM,
then this will be available in your <tt>PATH</tt>, and nothing further needs to
be done. If you've built LLVM yourself, or for any reason <tt>llvm-config</tt>
is not in your <tt>PATH</tt>, you'll need to pass the full path of
<tt>llvm-config</tt> to the build script.</p>
<p>You'll need to be <em>root</em> to install llvm-py. Remember that your <tt>PATH</tt>
is different from that of <em>root</em>, so even if <tt>llvm-config</tt> is in your
<tt>PATH</tt>, it may not be available when you do <tt>sudo</tt>.</p>
<h3>Steps</h3>
<p>The commands illustrated below assume that the LLVM source is available
under <tt>/home/mdevan/llvm</tt>. If you've a previous version of llvm-py
installed, you must remove it first, as described
<a href="#uninstall">below</a>.</p>
<p>If you have <tt>llvm-config</tt> in your path, you can build and install
llvm-py this way:</p>
<div class="listingblock">
<div class="content">
<pre><tt>$ tar jxvf llvm-py-0.2.tar.bz2
$ cd llvm-py-0.2
$ sudo python setup.py install</tt></pre>
</div></div>
<p>If you need to tell the build script where <tt>llvm-config</tt> is, do it this
way:</p>
<div class="listingblock">
<div class="content">
<pre><tt>$ tar jxvf llvm-py-0.2.tar.bz2
$ cd llvm-py-0.2
$ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Release/bin/llvm-config</tt></pre>
</div></div>
<p>To build a debug version of llvm-py, that links against the debug
libraries of LLVM, use this:</p>
<div class="listingblock">
<div class="content">
<pre><tt>$ tar jxvf llvm-py-0.2.tar.bz2
$ cd llvm-py-0.2
$ python setup.py build -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
$ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config</tt></pre>
</div></div>
<p>Be warned that debug binaries will be huge (65MB+) !</p>
<p><tt>setup.py</tt> is a standard Python distutils script. See the Python
documentation regarding <a href="http://docs.python.org/inst/inst.html">Installing
Python Modules</a> and <a href="http://docs.python.org/dist/dist.html">Distributing
Python Modules</a> for more information on such scripts.</p>
<h3><a id="uninstall"></a>Uninstall</h3>
<p>To get rid of llvm-py completely, if you wish to do so:</p>
<div class="listingblock">
<div class="content">
<pre><tt># rm -rf /usr/lib/python2.5/site-packages/llvm
# rm -f /usr/lib/python2.5/site-packages/llvm_py-0.1.egg-info</tt></pre>
</div></div>
<ul>
<li>
<p>
You need to be root to do this.
</p>
</li>
<li>
<p>
Paths are for debian-based systems, in other distros it might be different.
</p>
</li>
<li>
<p>
Note that there are version numbers (both Python's and llvm-py's)
which you might need to change to suit your system.
</p>
</li>
</ul>
</div>
<h2>The Concepts</h2>
<div class="sectionbody">
<p>This section explains a few concepts related to LLVM.</p>
<h3>Intermediate Representation</h3>
<p>The intermediate representation, or IR for short, is an in-memory data
structure that represents executable code. The IR data structures allow
for creation of types, constants, functions, function arguments,
instructions, global variables and so on. For example, to create a
function <em>sum</em> that takes two integers and returns their sum, we need to
follow these steps:</p>
<ul>
<li>
<p>
create an integer type <em>ti</em> of required bitwidth
</p>
</li>
<li>
<p>
create a function type <em>tf</em> which takes two <em>ti</em> -s and returns
another <em>ti</em>
</p>
</li>
<li>
<p>
create a function of type <em>tf</em> named <em>sum</em>
</p>
</li>
<li>
<p>
add a <em>basic block</em> to the function
</p>
</li>
<li>
<p>
using a helper object called an <em>instruction builder</em>, add two
instructions into the basic block:
</p>
<ol>
<li>
<p>
an instruction to add the two arguments and store the result into
a temporary variable
</p>
</li>
<li>
<p>
a return instruction to return the value of the temporary variable
</p>
</li>
</ol>
</li>
</ul>
<p>(A basic block is a block of instructions.)</p>
<p>LLVM has it's own instruction set; the instructions used above (<tt>add</tt>
and <tt>ret</tt>) are from this set. The LLVM instructions are at a higher
level than the usual assembly language; for example there are
instructions related to variable argument handling, exception handling,
and garbage collection. These allow high-level languages to be
represented cleanly in the IR.</p>
<h3>SSA Form and PHI Nodes</h3>
<p>All LLVM instructions are represented in the <em>Static Single Assignment</em>
(SSA) form. Essentially, this means that any variable can be assigned to
only once. Such a representation facilitates better optimization, among
other benefits.</p>
<p>A consequence of single assignment are PHI (&#934;) nodes. These
are required when a variable can be assigned a different value based on
the path of control flow. For example, the value of <tt>b</tt> at the end of
execution of the snippet below:</p>
<div class="listingblock">
<div class="content">
<pre><tt>a = 1;
if (v &lt; 10)
a = 2;
b = a;</tt></pre>
</div></div>
<p>cannot be determined statically. The value of <em>2</em> cannot be assigned to
the <em>original</em> <tt>a</tt>, since <tt>a</tt> can be assigned to only once. There are
two <tt>a</tt> 's in there, and the last assignment has to choose between which
version to pick. This is accomplished by adding a PHI node:</p>
<div class="listingblock">
<div class="content">
<pre><tt>a1 = 1;
if (v &lt; 10)
a2 = 2;
b = PHI(a1, a2);</tt></pre>
</div></div>
<p>The PHI node selects <tt>a1</tt> or <tt>a2</tt>, depending on where the control
reached the PHI node. The argument <tt>a1</tt> of the PHI node is associated
with the block <tt>"a1 = 1;"</tt> and <tt>a2</tt> with the block <tt>"a2 = 2;"</tt>.</p>
<p>PHI nodes have to be explicitly created in the LLVM IR. Accordingly the
LLVM instruction set has an instruction called <tt>phi</tt>.</p>
<h3>LLVM Assembly Language</h3>
<p>The LLVM IR can be represented offline in two formats
- a textual, human-readable form, similar to assembly language, called
the LLVM assembly language (files with .ll extension)
- a binary form, called the LLVM bitcode (files with .bc extension)
All three formats (the in-memory IR, the LLVM assembly language and the
LLVM bitcode) represent the <em>same</em> information. Each format can be
converted into the other two formats (using LLVM APIs).</p>
<p>The <a href="http://www.llvm.org/demo/">LLVM demo page</a> lets you type in C or C++
code, converts it into LLVM IR and outputs the IR as LLVM assembly
language code.</p>
<p>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):</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-style: italic"><span style="color: #9A1900">/* compute sum of 1..n */</span></span>
<span style="color: #009900">unsigned</span> <span style="font-weight: bold"><span style="color: #000000">sum</span></span><span style="color: #990000">(</span><span style="color: #009900">unsigned</span> n<span style="color: #990000">)</span>
<span style="color: #FF0000">{</span>
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="color: #990000">(</span>n <span style="color: #990000">==</span> <span style="color: #993399">0</span><span style="color: #990000">)</span>
<span style="font-weight: bold"><span style="color: #0000FF">return</span></span> <span style="color: #993399">0</span><span style="color: #990000">;</span>
<span style="font-weight: bold"><span style="color: #0000FF">else</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">return</span></span> n <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">sum</span></span><span style="color: #990000">(</span>n<span style="color: #990000">-</span><span style="color: #993399">1</span><span style="color: #990000">);</span>
<span style="color: #FF0000">}</span>
</tt></pre></div></div>
<p>The corresponding LLVM assembly:</p>
<div class="listingblock">
<div class="content">
<pre><tt>; ModuleID = '/tmp/webcompile/_4940_0.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i386-pc-linux-gnu"
define i32 @sum(i32 %n) nounwind {
entry:
%tmp215 = icmp eq i32 %n, 0 ; &lt;i1&gt; [#uses=1]
br i1 %tmp215, label %bb10, label %tailrecurse.bb10_crit_edge
tailrecurse.bb10_crit_edge: ; preds = %entry
%tmp = add i32 %n, -1 ; &lt;i32&gt; [#uses=3]
%tmp17 = mul i32 %tmp, %tmp ; &lt;i32&gt; [#uses=1]
%tmp18 = add i32 %tmp17, %n ; &lt;i32&gt; [#uses=1]
%tmp. = zext i32 %tmp to i64 ; &lt;i64&gt; [#uses=2]
%tmp19 = add i64 %tmp., -1 ; &lt;i64&gt; [#uses=1]
%tmp20 = mul i64 %tmp19, %tmp. ; &lt;i64&gt; [#uses=1]
%tmp21 = lshr i64 %tmp20, 1 ; &lt;i64&gt; [#uses=1]
%tmp.22 = trunc i64 %tmp21 to i32 ; &lt;i32&gt; [#uses=1]
%tmp24 = sub i32 %tmp18, %tmp.22 ; &lt;i32&gt; [#uses=1]
ret i32 %tmp24
bb10: ; preds = %entry
ret i32 0
}</tt></pre>
</div></div>
<p>Note the usage of SSA form and the total absence of any loop or
recursion at all! The long string called <tt>target datalayout</tt> is a
specification of the platform ABI (like endianness, sizes of types,
alignment etc.).</p>
<p>The <a href="http://www.llvm.org/docs/LangRef.html">LLVM Language Reference</a>
defines the LLVM assembly language including the entire instruction set.
The table below lists all the LLVM instructions. Each instruction links
to it's documentation.</p>
<div class="tableblock">
<table rules="all"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table: LLVM Instruction Set</caption>
<col width="240" />
<col width="560" />
<thead>
<tr>
<th align="left">
Category
</th>
<th align="left">
Instructions
</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td align="left">
Terminator instructions
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_ret">ret</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_br">br</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_switch">switch</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_invoke">invoke</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_unwind">unwind</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_unreachable">unreachable</a>
</td>
</tr>
<tr>
<td align="left">
Binary operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_add">add</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_sub">sub</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_mul">mul</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_udiv">udiv</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_sdiv">sdiv</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fdiv">fdiv</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_urem">urem</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_srem">srem</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_frem">frem</a>
</td>
</tr>
<tr>
<td align="left">
Bitwise binary operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_shl">shl</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_lshr">lshr</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_ashr">ashr</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_and">and</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_or">or</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_xor">xor</a>
</td>
</tr>
<tr>
<td align="left">
Vector operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_extractelement">extractelement</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_insertelement">insertelement</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_shufflevector">shufflevector</a>
</td>
</tr>
<tr>
<td align="left">
Aggregate operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_extractvalue">extractvalue</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_insertvalue">insertvalue</a>
</td>
</tr>
<tr>
<td align="left">
Memory access and addressing operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_malloc">malloc</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_free">free</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_alloca">alloca</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_load">load</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_store">store</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_getelementptr">getelementptr</a>
</td>
</tr>
<tr>
<td align="left">
Conversion operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_trunc">trunc</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_zext">zext</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_sext">sext</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fptrunc">fptrunc</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fpext">fpext</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fptoui">fptoui</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fptosi">fptosi</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_uitofp">uitofp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_sitofp">sitofp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_ptrtoint">ptrtoint</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_inttoptr">inttoptr</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_bitcast">bitcast</a>
</td>
</tr>
<tr>
<td align="left">
Other operations
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#i_icmp">icmp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_fcmp">fcmp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_vicmp">vicmp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_vfcmp">vfcmp</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_phi">phi</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_select">select</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_call">call</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_va_arg">va_arg</a>, <a href="http://www.llvm.org/docs/LangRef.html#i_getresult">getresult</a>
</td>
</tr>
<tr>
<td align="left">
Variable argument handling intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_va_start">llvm.va_start</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_va_end">llvm.va_end</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_va_copy">llvm.va_copy</a>
</td>
</tr>
<tr>
<td align="left">
Accurate garbage collection intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_returnaddress">llvm.returnaddress</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_frameaddress">llvm.frameaddress</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_stacksave">llvm.stacksave</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_stackrestore">llvm.stackrestore</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_prefetch">llvm.prefetch</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_pcmarker">llvm.pcmarker</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_readcyclecounter">llvm.readcyclecounter</a>
</td>
</tr>
<tr>
<td align="left">
Standard C library intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_memcpy">llvm.memcpy.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_memmove">llvm.memmove.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_memset">llvm.memset.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_sqrt">llvm.sqrt.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_powi">llvm.powi.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_sin">llvm.sin.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_cos">llvm.cos.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_pow">llvm.pow.*</a>
</td>
</tr>
<tr>
<td align="left">
Bit manipulation intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_bswap">llvm.bswap.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_ctpop">llvm.ctpop.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_ctlz">llvm.ctlz.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_cttz">llvm.cttz.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_part_select">llvm.part.select.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_part_set">llvm.part.set.*</a>
</td>
</tr>
<tr>
<td align="left">
Debugger intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_stoppoint">llvm.dbg.stoppoint</a>, <a href="http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_func_start">llvm.dbg.func.start</a>, <a href="http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_region_start">llvm.dbg.region.start</a>, <a href="http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_region_end">llvm.dbg.region.end</a>, <a href="http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_declare">llvm.dbg.declare</a>
</td>
</tr>
<tr>
<td align="left">
Exception handling intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_exception">llvm.eh_exception</a>, <a href="http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_selector">llvm.eh_selector</a>, <a href="http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_typeid_for">llvm.eh_typeid_for</a>
</td>
</tr>
<tr>
<td align="left">
Trampoline intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_it">llvm.init.trampoline</a>
</td>
</tr>
<tr>
<td align="left">
Atomic intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_memory_barrier">llvm.memory.barrier</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_atomic_lcs">llvm.atomic.lcs</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_atomic_las">llvm.atomic.las</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_atomic_swap">llvm.atomic.swap</a>
</td>
</tr>
<tr>
<td align="left">
General intrinsics
</td>
<td align="left">
<a href="http://www.llvm.org/docs/LangRef.html#int_var_annotation">llvm.var.annotation</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_annotation">llvm.annotation.*</a>, <a href="http://www.llvm.org/docs/LangRef.html#int_trap">llvm.trap</a>
</td>
</tr>
</tbody>
</table>
</div>
<p>Intrinsics (instructions that start with <tt>llvm.</tt>) are not yet available
in llvm-py.</p>
<h3>Modules</h3>
<p>Modules, in the LLVM IR, are similar to a single <em>C</em> language source
file (.c file). A module contains:</p>
<ul>
<li>
<p>
functions (declarations and definitions)
</p>
</li>
<li>
<p>
global variables and constants
</p>
</li>
<li>
<p>
global type aliases (typedef-s)
</p>
</li>
</ul>
<p>Modules are top-level containers; all executable code representation is
contained within modules.</p>
<h3>Optimization and Passes</h3>
<p>LLVM provides quite a few optimization algorithms that work on the IR.
These algorithms are organized as <em>passes</em>. Each pass does something
specific, like combining redundant instructions. Passes need not always
optimize the IR, it can also do other operations like inserting
instrumentation code, or analysing the IR (the result of which can be
used by passes that do optimizations) or even printing call graphs.</p>
<p>This LLVM <a href="http://www.llvm.org/docs/Passes.html">documentation page</a>
describes all the available passes, and what they do.</p>
<p>LLVM does not automatically choose to run any passes, anytime. Passes
have to be explicitly selected and run on each module. This gives you
the flexibility to choose transformations and optimizations that are
most suitable for the code in the module.</p>
<p>There is a LLVM binary called <a href="http://www.llvm.org/cmds/opt.html">opt</a>,
which lets you run passes on bitcode files from the command line. You
can write your own passes (in C/C++, as a shared library). This can be
loaded and executed by <tt>opt</tt>. (Although llvm-py does not allow you to
write your own passes, it does allow you to navigate the entire IR at
any stage, and perform any transforms on it as you like.)</p>
<p>Passes are run using a <em>pass manager</em>. TODO</p>
<h3>Execution Engine</h3>
<p>TODO</p>
<h3>BitCode</h3>
<p>TODO</p>
<h3>llvm-gcc</h3>
<p>TODO</p>
</div>
<h2>The llvm-py Package</h2>
<div class="sectionbody">
<p>The llvm-py is a Python package, consisting of 6 modules, that wrap
over enough LLVM APIs to allow the implementation of your own
compiler/VM backend in pure Python. If you're come this far, you
probably know why this is a good idea.</p>
<p>Out of the 6 modules, one is an "extension" module (i.e., it's written
in C), and another one is a private utility module, which leaves 4
public modules. These are:</p>
<ul>
<li>
<p>
<tt>llvm</tt> &#8212; top-level package, common classes (like exceptions)
</p>
</li>
<li>
<p>
<tt>llvm.core</tt> &#8212; IR-related APIs
</p>
</li>
<li>
<p>
<tt>llvm.ee</tt> &#8212; execution engine related APIs
</p>
</li>
<li>
<p>
<tt>llvm.passes</tt> &#8212; pass manager and passes related APIs
</p>
</li>
</ul>
<p>The modules contain only classes and (integer) constants. Mostly simple
Python constructs are used (deliberately) &#8212;
<a href="http://docs.python.org/lib/built-in-funcs.html">property()</a> and
<a href="http://wiki.python.org/moin/PythonDecoratorLibrary">property
decorators</a> are probably the most exotic animals around. All classes are
the "new style" classes. The APIs are designed to be navigable (and
guessable!) once you know a few conventions. These conventions are
highlighted in the sections below.</p>
<p>Here is a quick overview of the contents of each package:</p>
<div class="title">llvm</div><ul>
<li>
<p>
LLVMException &#8212; exception class (currently the only one)
</p>
</li>
</ul>
<div class="title">llvm.core</div><ul>
<li>
<p>
Module &#8212; represents an LLVM Module
</p>
</li>
<li>
<p>
Type &#8212; represents an LLVM Type
</p>
</li>
<li>
<p>
IntegerType, FunctionType, StructType, ArrayType, PointerType,
VectorType &#8212; derived classes of Type
</p>
</li>
<li>
<p>
TypeHandle &#8212; used for constructing recursive (self-referencing) types
(e.g. linked list nodes)
</p>
</li>
<li>
<p>
Value &#8212; represents an LLVM Value
</p>
</li>
<li>
<p>
Constant, GlobalValue, GlobalVariable, Argument, Function,
Instruction, CallOrInvokeInstruction, PHINode, SwitchInstruction &#8212;
various derived classes of Value
</p>
</li>
<li>
<p>
BasicBlock &#8212; another derived of Value, represents an LLVM basic block
</p>
</li>
<li>
<p>
Builder &#8212; used for creating instructions, wraps LLVM IRBuilder helper
class
</p>
</li>
<li>
<p>
ModuleProvider &#8212; required to use modules in execution engine and pass
manager
</p>
</li>
<li>
<p>
constants <tt>TYPE_*</tt> that represents various types
</p>
</li>
<li>
<p>
constants <tt>CC_*</tt> that represent calling conventions
</p>
</li>
<li>
<p>
constants <tt>IPRED_*</tt> and <tt>RPRED_*</tt> that represent integer and real
comparison predicates (like less than, greater than etc.)
</p>
</li>
<li>
<p>
constants <tt>LINKAGE_*</tt> that represent linkage of symbols (external,
internal etc.)
</p>
</li>
<li>
<p>
constants <tt>VISIBILITY_*</tt> that represents visibility of symbols
(default, hidden, protected)
</p>
</li>
<li>
<p>
constants <tt>ATTR_*</tt> that represent function parameter attributes
</p>
</li>
</ul>
<div class="title">llvm.ee</div><ul>
<li>
<p>
ExecutionEngine &#8212; represents an execution engine (which can be an
either an interpreter or a JIT)
</p>
</li>
<li>
<p>
TargetData &#8212; represents the ABI of the target platform (details like
sizes and alignment of primitive types, endinanness etc)
</p>
</li>
</ul>
<div class="title">llvm.passes</div><ul>
<li>
<p>
PassManager &#8212; represents an LLVM pass manager
</p>
</li>
<li>
<p>
FunctionPassManager &#8212; represents an LLVM function pass manager
</p>
</li>
<li>
<p>
constants <tt>PASS_*</tt> that represent various passes
</p>
</li>
</ul>
<div class="title">A note on the 'import'ing of these modules</div>
<p>Pythonically, modules are imported with the statement <tt>"import
llvm.core"</tt> and not <tt>"from llvm.core import *"</tt>. However, you might find
it more convenient to import llvm-py modules thus:</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
<span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm<span style="color: #990000">.</span>core <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
<span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm<span style="color: #990000">.</span>ee <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
<span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm<span style="color: #990000">.</span>passes <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
</tt></pre></div></div>
<p>This avoids quite some typing. Both conventions work, however.</p>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<img src="./images/icons/tip.png" alt="Tip" />
</td>
<td class="content">Python-style documentation strings (<tt><em>doc</em></tt>) are present in
llvm-py. You can use the <tt>help()</tt> of the interactive Python
interpreter or the <tt>object?</tt> of <a href="http://ipython.scipy.org/moin/">IPython</a>
to get online help. (Note: not complete yet!)</td>
</tr></table>
</div>
<h3>Module (llvm.core)</h3>
<p>Modules are top-level container objects. You need to create a module
object first, before you can add global variables, aliases or functions.
Modules are created using the static method <tt>Module.new</tt>:</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-style: italic"><span style="color: #9A1900">#!/usr/bin/env python</span></span>
<span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
<span style="font-weight: bold"><span style="color: #000080">from</span></span> llvm<span style="color: #990000">.</span>core <span style="font-weight: bold"><span style="color: #000080">import</span></span> <span style="color: #990000">*</span>
<span style="font-style: italic"><span style="color: #9A1900"># create a module</span></span>
my<span style="color: #009900">_</span>module <span style="color: #990000">=</span> <span style="color: #009900">Module</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">new</span></span><span style="color: #990000">(</span><span style="color: #FF0000">'my_module'</span><span style="color: #990000">)</span>
</tt></pre></div></div>
<p>The constructor of the Module class should <strong>not</strong> be used to instantiate
a Module object. This is a common feature for all llvm-py classes.</p>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<img src="./images/icons/tip.png" alt="Tip" />
</td>
<td class="content">
<div class="title">Convention</div>
<p><strong>All</strong> llvm-py objects are instantiated using static methods of
corresponding classes. Constructors <em>should not</em> be used.</p>
</td>
</tr></table>
</div>
<p>The argument <tt>my_module</tt> is a module identifier (a plain string). The
attributes of the <tt>Module</tt> class is:</p>
<div class="exampleblock">
<div class="title">llvm.core.Module</div>
<div class="exampleblock-content">
<div class="title">Static Constructors</div><dl>
<dt>
<tt>new(module_id)</tt>
</dt>
<dd>
<p>
create a new <tt>Module</tt> instance with given <tt>module_id</tt>. The <tt>module_id</tt>
should be a string.
</p>
</dd>
</dl>
<div class="title">Properties</div><dl>
<dt>
<tt>data_layout</tt>
</dt>
<dd>
<p>
a string representing the ABI of the platform
</p>
</dd>
<dt>
<tt>target</tt>
</dt>
<dd>
<p>
a string like <tt>i386-pc-linux-gnu</tt> or <tt>i386-pc-solaris2.8</tt>
</p>
</dd>
<dt>
<tt>global_variables</tt> [read-only]
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>functions</tt> [read-only]
</dt>
<dd>
<p>
TODO
</p>
</dd>
</dl>
<div class="title">Methods</div><dl>
<dt>
<tt>add_type_name</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>delete_type_name</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>add_global_variable</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>get_global_variable_named</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>add_function</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>get_function_named</tt>
</dt>
<dd>
<p>
TODO
</p>
</dd>
<dt>
<tt>verify</tt>
</dt>
<dd>
<p>
Verifies the correctness of the module. Raises <tt>LLVMException</tt> on
errors.
</p>
</dd>
</dl>
<div class="title">Special Methods</div><dl>
<dt>
<tt>__str__</tt>
</dt>
<dd>
<p>
<tt>Module</tt> objects can be stringified into it's LLVM assembly language
representation.
</p>
</dd>
<dt>
<tt>__eq__</tt>
</dt>
<dd>
<p>
<tt>Module</tt> objects can be compared for equality. Internally, this
converts both arguments into their LLVM assembly representations and
compares the resultant strings.
</p>
</dd>
</dl>
</div></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<img src="./images/icons/tip.png" alt="Tip" />
</td>
<td class="content">
<div class="title">Convention</div>
<p><strong>All</strong> llvm-py objects (where it makes sense), when stringified, return
the LLVM assembly representation. &#8220; <tt>print module_obj</tt> &#8221; for example,
prints the LLVM assembly form of the entire module.</p>
<p>Such objects, when compared for equality, internally compare these
string representations.</p>
</td>
</tr></table>
</div>
<h3>Types (llvm.core)</h3>
<p>Types are what you think they are. A instance of <tt>llvm.core.Type</tt>, or
one of its derived classes, represent a type. llvm-py does not use as
many classes to represent types as does LLVM itself. Some types are
represented using <tt>llvm.core.Type</tt> itself and the rest are represented
using derived classes of <tt>llvm.core.Type</tt>. As usual, an instance is created
via one of the static methods of <tt>Type</tt>. These methods return an
instance of either <tt>llvm.core.Type</tt> itself or one of its derived
classes.</p>
<p>The following table lists all the available types along with the static
method which has to be used to construct it and the name of the class whose
object is actually returned by the static method.</p>
<div class="tableblock">
<table rules="all"
frame="border"
cellspacing="0" cellpadding="4">
<col width="400" />
<col width="240" />
<col width="160" />
<thead>
<tr>
<th align="left">
Name
</th>
<th align="left">
Constructor Method
</th>
<th align="left">
Class
</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td align="left">
integer of bitwidth <tt>n</tt>
</td>
<td align="left">
<tt>Type.int(n)</tt>
</td>
<td align="left">
<tt>IntegerType</tt>
</td>
</tr>
<tr>
<td align="left">
32-bit float
</td>
<td align="left">
<tt>Type.float()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
64-bit double
</td>
<td align="left">
<tt>Type.double()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
80-bit float
</td>
<td align="left">
<tt>Type.x86_fp80()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
128-bit float (112-bit mantissa)
</td>
<td align="left">
<tt>Type.fp128()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
128-bit float (two 64-bits)
</td>
<td align="left">
<tt>Type.ppc_fp128()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
function
</td>
<td align="left">
<tt>Type.function(r, p, v)</tt>
</td>
<td align="left">
<tt>FunctionType</tt>
</td>
</tr>
<tr>
<td align="left">
unpacked struct
</td>
<td align="left">
<tt>Type.struct(eltys)</tt>
</td>
<td align="left">
<tt>StructType</tt>
</td>
</tr>
<tr>
<td align="left">
packed struct
</td>
<td align="left">
<tt>Type.packed_struct(eltys)</tt>
</td>
<td align="left">
<tt>StructType</tt>
</td>
</tr>
<tr>
<td align="left">
array
</td>
<td align="left">
<tt>Type.array(elty, count)</tt>
</td>
<td align="left">
<tt>ArrayType</tt>
</td>
</tr>
<tr>
<td align="left">
pointer to value of type <tt>pty</tt>
</td>
<td align="left">
<tt>Type.pointer(pty, addrspc)</tt>
</td>
<td align="left">
<tt>PointerType</tt>
</td>
</tr>
<tr>
<td align="left">
vector
</td>
<td align="left">
<tt>Type.vector(elty, count)</tt>
</td>
<td align="left">
<tt>VectorType</tt>
</td>
</tr>
<tr>
<td align="left">
void
</td>
<td align="left">
<tt>Type.void()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
label
</td>
<td align="left">
<tt>Type.label()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
<tr>
<td align="left">
opaque
</td>
<td align="left">
<tt>Type.opaque()</tt>
</td>
<td align="left">
<tt>Type</tt>
</td>
</tr>
</tbody>
</table>
</div>
<p>The class hierarchy is:</p>
<div class="listingblock">
<div class="content">
<pre><tt>Type
IntegerType
FunctionType
StructType
ArrayType
PointerType
VectorType</tt></pre>
</div></div>
<p>The class-level documentation follows:</p>
<div class="exampleblock">
<div class="title">llvm.core.Type</div>
<div class="exampleblock-content">
<div class="title">Static Constructors</div><dl>
<dt>
<tt>int(n)</tt>
</dt>
<dd>
<p>
Create an integer type of bit width <tt>n</tt>.
</p>
</dd>
<dt>
<tt>float()</tt>
</dt>
<dd>
<p>
Create a 32-bit floating point type.
</p>
</dd>
<dt>
<tt>double()</tt>
</dt>
<dd>
<p>
Create a 64-bit floating point type.
</p>
</dd>
<dt>
<tt>x86_fp80()</tt>
</dt>
<dd>
<p>
Create a 80-bit 80x87-style floating point type.
</p>
</dd>
<dt>
<tt>fp128()</tt>
</dt>
<dd>
<p>
Create a 128-bit floating point type (112-bit mantissa).
</p>
</dd>
<dt>
<tt>ppc_fp128()</tt>
</dt>
<dd>
<p>
Create a 128-bit float (two 64-bits).
</p>
</dd>
<dt>
<tt>function(ret, params, vararg=False)</tt>
</dt>
<dd>
<p>
Create a function type, having the return type <tt>ret</tt> (must be a
<tt>Type</tt>), accepting the parameters <tt>params</tt>, where <tt>params</tt> is an
iterable, that yields <tt>Type</tt> objects representing the type of
each function argument in order. If <tt>vararg</tt> is <tt>True</tt>, function is
variadic.
</p>
</dd>
<dt>
<tt>struct(eltys)</tt>
</dt>
<dd>
<p>
Create an unpacked structure. <tt>eltys</tt> is an iterable, that yields
<tt>Type</tt> objects representing the type of each element in order.
</p>
</dd>
<dt>
<tt>packed_struct(eltys)</tt>
</dt>
<dd>
<p>
Like <tt>struct(eltys)</tt>, but creates a packed struct.
</p>
</dd>
<dt>
<tt>array(elty, count)</tt>
</dt>
<dd>
<p>
Creates an array type, holding <tt>count</tt> elements, each of type <tt>elty</tt>
(which should be a <tt>Type</tt>).
</p>
</dd>
<dt>
<tt>pointer(pty, addrspc=0)</tt>
</dt>
<dd>
<p>
Create a pointer to type <tt>pty</tt> (which should be a `Type). (TODO
addrspc).
</p>
</dd>
<dt>
<tt>void()</tt>
</dt>
<dd>
<p>
Creates a void type. Used for function return types.
</p>
</dd>
<dt>
<tt>label()</tt>
</dt>
<dd>
<p>
Creates a label type.
</p>
</dd>
<dt>
<tt>opaque()</tt>
</dt>
<dd>
<p>
Opaque type, used for creating self-referencing types.
</p>
</dd>
</dl>
<div class="title">Properties</div><dl>
<dt>
<tt>kind</tt> [read-only]
</dt>
<dd>
<p>
A value (enum) representing the &#8220;type&#8221; of the object. It will be
one of the following constants defined in <tt>llvm.core</tt>:
</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #009900">TYPE_VOID</span> <span style="color: #990000">=</span> <span style="color: #993399">0</span>
<span style="color: #009900">TYPE_FLOAT</span> <span style="color: #990000">=</span> <span style="color: #993399">1</span>
<span style="color: #009900">TYPE_DOUBLE</span> <span style="color: #990000">=</span> <span style="color: #993399">2</span>
<span style="color: #009900">TYPE_X86_FP80</span> <span style="color: #990000">=</span> <span style="color: #993399">3</span>
<span style="color: #009900">TYPE_FP128</span> <span style="color: #990000">=</span> <span style="color: #993399">4</span>
<span style="color: #009900">TYPE_PPC_FP128</span> <span style="color: #990000">=</span> <span style="color: #993399">5</span>
<span style="color: #009900">TYPE_LABEL</span> <span style="color: #990000">=</span> <span style="color: #993399">6</span>
<span style="color: #009900">TYPE_INTEGER</span> <span style="color: #990000">=</span> <span style="color: #993399">7</span>
<span style="color: #009900">TYPE_FUNCTION</span> <span style="color: #990000">=</span> <span style="color: #993399">8</span>
<span style="color: #009900">TYPE_STRUCT</span> <span style="color: #990000">=</span> <span style="color: #993399">9</span>
<span style="color: #009900">TYPE_ARRAY</span> <span style="color: #990000">=</span> <span style="color: #993399">10</span>
<span style="color: #009900">TYPE_POINTER</span> <span style="color: #990000">=</span> <span style="color: #993399">11</span>
<span style="color: #009900">TYPE_OPAQUE</span> <span style="color: #990000">=</span> <span style="color: #993399">12</span>
<span style="color: #009900">TYPE_VECTOR</span> <span style="color: #990000">=</span> <span style="color: #993399">13</span>
</tt></pre></div></div>
<p>Example:</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">().</span>kind <span style="color: #990000">==</span> <span style="color: #009900">TYPE_INTEGER</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">void</span></span><span style="color: #990000">().</span>kind <span style="color: #990000">==</span> <span style="color: #009900">TYPE_VOID</span>
</tt></pre></div></div>
</dd>
</dl>
<div class="title">Methods</div><dl>
<dt>
<tt>refine</tt>
</dt>
<dd>
<p>
Used for constructing self-referencing types. See the documentation
of <tt>TypeHandle</tt> objects.
</p>
</dd>
</dl>
<div class="title">Special Methods</div><dl>
<dt>
<tt>__str__</tt>
</dt>
<dd>
<p>
<tt>Type</tt> objects can be stringified into it's LLVM assembly language
representation.
</p>
</dd>
<dt>
<tt>__eq__</tt>
</dt>
<dd>
<p>
<tt>Type</tt> objects can be compared for equality. Internally, this
converts both arguments into their LLVM assembly representations and
compares the resultant strings.
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.IntegerType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>width</tt> [read-only]
</dt>
<dd>
<p>
The width of the integer type, in number of bits.
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.FunctionType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>return_type</tt> [read-only]
</dt>
<dd>
<p>
A <tt>Type</tt> object, representing the return type of the function.
</p>
</dd>
<dt>
<tt>vararg</tt> [read-only]
</dt>
<dd>
<p>
<tt>True</tt> if the function is variadic.
</p>
</dd>
<dt>
<tt>args</tt> [read-only]
</dt>
<dd>
<p>
Returns an iterable object that yields <tt>Type</tt> objects that
represent, in order, the types of the arguments accepted by the
function. Used like this:
</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>func<span style="color: #009900">_</span>type <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">function</span></span><span style="color: #990000">(</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(),</span> <span style="color: #990000">[</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(),</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span> <span style="color: #990000">]</span> <span style="color: #990000">)</span>
<span style="font-weight: bold"><span style="color: #0000FF">for</span></span> arg <span style="font-weight: bold"><span style="color: #0000FF">in</span></span> func<span style="color: #009900">_</span>type<span style="color: #990000">.</span>args<span style="color: #990000">:</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> arg<span style="color: #990000">.</span>kind <span style="color: #990000">==</span> <span style="color: #009900">TYPE_INTEGER</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> arg <span style="color: #990000">==</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> func<span style="color: #009900">_</span>type<span style="color: #990000">.</span>arg<span style="color: #009900">_</span>count <span style="color: #990000">==</span> <span style="font-weight: bold"><span style="color: #000000">len</span></span><span style="color: #990000">(</span>func<span style="color: #009900">_</span>type<span style="color: #990000">.</span>args<span style="color: #990000">)</span>
</tt></pre></div></div>
</dd>
<dt>
<tt>arg_count</tt> [read-only]
</dt>
<dd>
<p>
The number of arguments. Same as <tt>len(obj.args)</tt>, but faster.
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.StructType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>packed</tt> [read-only]
</dt>
<dd>
<p>
<tt>True</tt> if the structure is packed (no padding between elements).
</p>
</dd>
<dt>
<tt>elements</tt> [read-only]
</dt>
<dd>
<p>
Returns an iterable object that yields <tt>Type</tt> objects that
represent, in order, the types of the elements of the structure.
Used like this:
</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>struct<span style="color: #009900">_</span>type <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">struct</span></span><span style="color: #990000">(</span> <span style="color: #990000">[</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(),</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span> <span style="color: #990000">]</span> <span style="color: #990000">)</span>
<span style="font-weight: bold"><span style="color: #0000FF">for</span></span> elem <span style="font-weight: bold"><span style="color: #0000FF">in</span></span> struct<span style="color: #009900">_</span>type<span style="color: #990000">.</span>elements<span style="color: #990000">:</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> elem<span style="color: #990000">.</span>kind <span style="color: #990000">==</span> <span style="color: #009900">TYPE_INTEGER</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> elem <span style="color: #990000">==</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span>
<span style="font-weight: bold"><span style="color: #0000FF">assert</span></span> struct<span style="color: #009900">_</span>type<span style="color: #990000">.</span>element<span style="color: #009900">_</span>count <span style="color: #990000">==</span> <span style="font-weight: bold"><span style="color: #000000">len</span></span><span style="color: #990000">(</span>struct<span style="color: #009900">_</span>type<span style="color: #990000">.</span>elements<span style="color: #990000">)</span>
</tt></pre></div></div>
</dd>
<dt>
<tt>element_count</tt> [read-only]
</dt>
<dd>
<p>
The number of elements. Same as <tt>len(obj.elements)</tt>, but faster.
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.ArrayType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>element</tt> [read-only]
</dt>
<dd>
<p>
A <tt>Type</tt> object representing the type of the element of the array.
</p>
</dd>
<dt>
<tt>count</tt> [read-only]
</dt>
<dd>
<p>
The number of elements in the array.
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.PointerType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>address_space</tt> [read-only]
</dt>
<dd>
<p>
The address space of the pointer.
</p>
</dd>
<dt>
<tt>pointee</tt> [read-only]
</dt>
<dd>
<p>
TODO <strong>missing</strong>
</p>
</dd>
</dl>
</div></div>
<div class="exampleblock">
<div class="title">llvm.core.VectorType</div>
<div class="exampleblock-content">
<div class="title">Base Class</div><ul>
<li>
<p>
<tt>llvm.core.Type</tt>
</p>
</li>
</ul>
<div class="title">Properties</div><dl>
<dt>
<tt>element</tt> [read-only]
</dt>
<dd>
<p>
A <tt>Type</tt> object representing the type of the element of the vector.
</p>
</dd>
<dt>
<tt>count</tt> [read-only]
</dt>
<dd>
<p>
The number of elements in the vector.
</p>
</dd>
</dl>
</div></div>
<p>Here is an example that demonstrates the creation of types:</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-style: italic"><span style="color: #9A1900">#!/usr/bin/env python</span></span>
<span style="font-style: italic"><span style="color: #9A1900"># integers</span></span>
int<span style="color: #009900">_</span>ty <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span>
bool<span style="color: #009900">_</span>ty <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span><span style="color: #993399">1</span><span style="color: #990000">)</span>
int<span style="color: #009900">_</span>64bit <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span><span style="color: #993399">64</span><span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># floats</span></span>
sprec<span style="color: #009900">_</span>real <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">float</span></span><span style="color: #990000">()</span>
dprec<span style="color: #009900">_</span>real <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">double</span></span><span style="color: #990000">()</span>
<span style="font-style: italic"><span style="color: #9A1900"># arrays and vectors</span></span>
intar<span style="color: #009900">_</span>ty <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">array</span></span><span style="color: #990000">(</span> int<span style="color: #009900">_</span>ty<span style="color: #990000">,</span> <span style="color: #993399">10</span> <span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># "typedef int intar_ty[10];"</span></span>
twodim <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">array</span></span><span style="color: #990000">(</span> intar<span style="color: #009900">_</span>ty <span style="color: #990000">,</span> <span style="color: #993399">10</span> <span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># "typedef int twodim[10][10];"</span></span>
vec <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">array</span></span><span style="color: #990000">(</span> int<span style="color: #009900">_</span>ty<span style="color: #990000">,</span> <span style="color: #993399">10</span> <span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># structures</span></span>
s1<span style="color: #009900">_</span>ty <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">struct</span></span><span style="color: #990000">(</span> <span style="color: #990000">[</span> int<span style="color: #009900">_</span>ty<span style="color: #990000">,</span> sprec<span style="color: #009900">_</span>real <span style="color: #990000">]</span> <span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># "struct s1_ty { int v1; float v2; };"</span></span>
<span style="font-style: italic"><span style="color: #9A1900"># pointers</span></span>
intptr<span style="color: #009900">_</span>ty <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">pointer</span></span><span style="color: #990000">(</span>int<span style="color: #009900">_</span>ty<span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># "typedef int *intptr_ty;"</span></span>
<span style="font-style: italic"><span style="color: #9A1900"># functions</span></span>
f1 <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">function</span></span><span style="color: #990000">(</span> int<span style="color: #009900">_</span>ty<span style="color: #990000">,</span> <span style="color: #990000">[</span> int<span style="color: #009900">_</span>ty <span style="color: #990000">]</span> <span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># functions that take 1 int_ty and return 1 int_ty</span></span>
f2 <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">function</span></span><span style="color: #990000">(</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">void</span></span><span style="color: #990000">(),</span> <span style="color: #990000">[</span> int<span style="color: #009900">_</span>ty <span style="color: #990000">]</span> <span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># functions that take 1 int_ty and return nothing</span></span>
fnargs <span style="color: #990000">=</span> <span style="color: #990000">[</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">pointer</span></span><span style="color: #990000">(</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span><span style="color: #993399">8</span><span style="color: #990000">)</span> <span style="color: #990000">)</span> <span style="color: #990000">]</span>
printf <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">function</span></span><span style="color: #990000">(</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(),</span> fnargs<span style="color: #990000">,</span> <span style="color: #009900">True</span> <span style="color: #990000">)</span>
<span style="font-style: italic"><span style="color: #9A1900"># variadic function</span></span>
</tt></pre></div></div>
<h3>Values (llvm.core)</h3>
<p><tt>llvm.core.Value</tt> is the base class of all values computed by a program
that may be used as operands to other values. A value has a type
associated with it (an object of <tt>llvm.core.Type</tt>).</p>
<p>The class hierarchy is:</p>
<div class="listingblock">
<div class="content">
<pre><tt>Value
Constant
GlobalValue
GlobalVariable
Function
Argument
Instruction
CallOrInvokeInstruction
PHINode
SwitchInstruction
BasicBlock</tt></pre>
</div></div>
<p>The <tt>Value</tt> class is abstract, it's not meant to be instantiated.
<tt>Constant</tt>-s represent constants that appear within code or as
initializers of globals. They are constructed using static methods of
<tt>Constant</tt>. The <tt>Constant</tt> class is covered in a separate section below.
The <tt>Function</tt> object represents an instance of a function type. Such
objects contain <tt>Argument</tt> objects, which represent the actual,
local-variable-like arguments of the function (not to be confused with
the arguments returned by a function <em>type</em> object &#8212; these represent
the <em>type</em> of the arguments). The various <tt>Instruction</tt>-s are created by
the <tt>Builder</tt> class. These are also covered separately.</p>
<p><tt>Value</tt> objects have a type (read-only), and a name (read-write).</p>
<div class="exampleblock">
<div class="title">llvm.core.Value</div>
<div class="exampleblock-content">
<div class="title">Properties</div><dl>
<dt>
<tt>name</tt>
</dt>
<dd>
<p>
The name of the value.
</p>
</dd>
<dt>
<tt>type</tt> [read-only]
</dt>
<dd>
<p>
An <tt>llvm.core.Type</tt> object representing the type of the value.
</p>
</dd>
</dl>
<div class="title">Special Methods</div><dl>
<dt>
<tt>__str__</tt>
</dt>
<dd>
<p>
<tt>Value</tt> objects can be stringified into it's LLVM assembly language
representation.
</p>
</dd>
<dt>
<tt>__eq__</tt>
</dt>
<dd>
<p>
<tt>Value</tt> objects can be compared for equality. Internally, this
converts both arguments into their LLVM assembly representations and
compares the resultant strings.
</p>
</dd>
</dl>
</div></div>
<h3>Constants (llvm.core)</h3>
<p><tt>Constant</tt>-s represents constants that appear within the code. The
values of such objects are known at creation time. Constants can be
created from Python constants. A constant expression is also a constant
&#8212; given a <tt>Constant</tt> object, an operation (like addition, subtraction
etc) can be specified, to yield a new <tt>Constant</tt> object. Let's see some
examples:</p>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-style: italic"><span style="color: #9A1900">#!/usr/bin/env python</span></span>
ti <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">()</span> <span style="font-style: italic"><span style="color: #9A1900"># a 32-bit int type</span></span>
k1 <span style="color: #990000">=</span> <span style="color: #009900">Constant</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span>ti<span style="color: #990000">,</span> <span style="color: #993399">42</span><span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># "int k1 = 42;"</span></span>
k2 <span style="color: #990000">=</span> k1<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">add</span></span><span style="color: #990000">(</span> <span style="color: #009900">Constant</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span> ti<span style="color: #990000">,</span> <span style="color: #993399">10</span> <span style="color: #990000">)</span> <span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># "int k2 = k1 + 10;"</span></span>
tr <span style="color: #990000">=</span> <span style="color: #009900">Type</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">float</span></span><span style="color: #990000">()</span>
r1 <span style="color: #990000">=</span> <span style="color: #009900">Constant</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">real</span></span><span style="color: #990000">(</span>tr<span style="color: #990000">,</span> <span style="color: #FF0000">"3.141592"</span><span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># create from a string</span></span>
r2 <span style="color: #990000">=</span> <span style="color: #009900">Constant</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">real</span></span><span style="color: #990000">(</span>tr<span style="color: #990000">,</span> <span style="color: #993399">1.61803399</span><span style="color: #990000">)</span> <span style="font-style: italic"><span style="color: #9A1900"># create from a Python float</span></span>
</tt></pre></div></div>
<h3>TypeHandle (llvm.core)</h3>
<p>TODO</p>
<h3>Instructions (llvm.core)</h3>
<p>TODO</p>
<h3>Basic Block (llvm.core)</h3>
<p>TODO</p>
<h3>Builder (llvm.core)</h3>
<p>TODO</p>
<h3>Module Provider (llvm.core)</h3>
<p>TODO</p>
<h3>Execution Engine (llvm.ee)</h3>
<p>TODO</p>
<h3>Target Data (llvm.ee)</h3>
<p>TODO</p>
<h3>Pass Managers and Passes (llvm.passes)</h3>
<p>TODO</p>
</div>
<h2>Annotated Examples</h2>
<div class="sectionbody">
<p>TODO</p>
</div>
<h2>About the llvm-py Project</h2>
<div class="sectionbody">
<p>llvm-py lives at
<a href="http://mdevan.nfshost.com/llvm-py/">http://mdevan.nfshost.com/llvm-py/</a>.
The code (subversion repository) and the issue tracker are hosted on google
code, at
<a href="http://code.google.com/p/llvm-py/">http://code.google.com/p/llvm-py/</a>.
llvm-py is distributed under the new BSD license, the full license
text is in the file named
<a href="http://code.google.com/p/llvm-py/source/browse/trunk/LICENSE">LICENSE</a>
available in the source distribution.</p>
<p>The entire llvm-py website is generated from marked up text files
using the tool <a href="http://www.methods.co.nz/asciidoc/"><em>AsciiDoc</em></a>. These text
files and the generated HTML pages are available in the source
distribution.</p>
<p>llvm-py is an ongoing, live project. Your contributions in any form
are most welcome. You can checkout the latest SVN HEAD from
<a href="http://code.google.com/p/llvm-py/source/checkout">here</a>.</p>
<p>Mahadevan R wrote llvm-py and works on it in his spare time. He can be
reached at <em>mdevan.foobar@gmail.com</em>.</p>
</div>
<div id="footer">
<div id="footer-text">
Web pages &copy; Mahadevan R. Generated with <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.
Last updated 18-Jun-2008.
</div>
</div>
</div>
</td>
</tr>
</table>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-4519056-2");
pageTracker._initData();
pageTracker._trackPageview();
</script>
</body>
</html>