updated docs. git-svn-id: http://llvm-py.googlecode.com/svn/trunk@27 8d1e9007-1d4e-0410-b67e-1979fd6579aa
2662 lines
104 KiB
HTML
2662 lines
104 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="Python bindings for LLVM" />
|
|
<meta name="keywords" content="llvm python compiler backend bindings" />
|
|
<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" />
|
|
<script type="text/javascript">
|
|
/*<![CDATA[*/
|
|
window.onload = function(){generateToc(2)}
|
|
/*]]>*/
|
|
</script>
|
|
<script type="text/javascript" src="js/toc.js"></script>
|
|
<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>»<a href="index.html">Home</a></div>
|
|
<div>»<a href="examples.html">Examples</a></div>
|
|
<div>»<a href="download.html">Download</a></div>
|
|
<div>»<a href="userguide.html">User Guide</a></div>
|
|
<div>»<a href="contribute.html">Contribute</a></div>
|
|
<div>»<a href="license.html">License</a></div>
|
|
<div>»<a href="about.html">About</a></div>
|
|
</td>
|
|
<td>
|
|
<div id="toc" style="float: right; display: none">
|
|
<div id="toctitle">Table of Contents</div>
|
|
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
|
|
</div>
|
|
<div id="layout-content">
|
|
<div id="header">
|
|
<h1>llvm-py User Guide</h1>
|
|
</div>
|
|
<div id="preamble">
|
|
<div class="sectionbody">
|
|
<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 (i386, amd64)
|
|
and OpenBSD (i386, amd64). 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 <tt>sudo apt-get install gcc g++ python python-dev</tt>. 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 “ocamldoc”
|
|
first.</p>
|
|
<h3>LLVM and <tt>—enable-pic</tt></h3>
|
|
<p>The result of an LLVM build is a set of static libraries and object
|
|
files. The llvm-py 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 <tt>-fPIC</tt> option (generate position
|
|
independent code). Be sure to use the <tt>—enable-pic</tt> option while
|
|
configuring LLVM (default is no PIC), like this:</p>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre><tt>~/llvm-2.3$ ./configure --enable-pic --enable-optimized</tt></pre>
|
|
</div></div>
|
|
<h3>llvm-config</h3>
|
|
<p>Inorder to build llvm-py, it's build script needs to know from where it
|
|
can 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 (Φ) 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 < 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 < 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 ; <i1> [#uses=1]
|
|
br i1 %tmp215, label %bb10, label %tailrecurse.bb10_crit_edge
|
|
|
|
tailrecurse.bb10_crit_edge: ; preds = %entry
|
|
%tmp = add i32 %n, -1 ; <i32> [#uses=3]
|
|
%tmp17 = mul i32 %tmp, %tmp ; <i32> [#uses=1]
|
|
%tmp18 = add i32 %tmp17, %n ; <i32> [#uses=1]
|
|
%tmp. = zext i32 %tmp to i64 ; <i64> [#uses=2]
|
|
%tmp19 = add i64 %tmp., -1 ; <i64> [#uses=1]
|
|
%tmp20 = mul i64 %tmp19, %tmp. ; <i64> [#uses=1]
|
|
%tmp21 = lshr i64 %tmp20, 1 ; <i64> [#uses=1]
|
|
%tmp.22 = trunc i64 %tmp21 to i32 ; <i32> [#uses=1]
|
|
%tmp24 = sub i32 %tmp18, %tmp.22 ; <i32> [#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 <tt>C</tt> 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 an 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 is
|
|
written in C), and another one is a small private utility module, which
|
|
leaves 4 public modules. These are:</p>
|
|
<ul>
|
|
<li>
|
|
<p>
|
|
<tt>llvm</tt> — top-level package, common classes (like exceptions)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<tt>llvm.core</tt> — IR-related APIs
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<tt>llvm.ee</tt> — execution engine related APIs
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<tt>llvm.passes</tt> — 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) —
|
|
<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
|
|
"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 — exception class (currently the only one)
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
<div class="title">llvm.core</div><ul>
|
|
<li>
|
|
<p>
|
|
Module — represents an LLVM Module
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Type — represents an LLVM Type
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
IntegerType, FunctionType, StructType, ArrayType, PointerType,
|
|
VectorType — derived classes of Type
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
TypeHandle — used for constructing recursive (self-referencing) types
|
|
(e.g. linked list nodes)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Value — represents an LLVM Value
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Constant, GlobalValue, GlobalVariable, Argument, Function,
|
|
Instruction, CallOrInvokeInstruction, PHINode, SwitchInstruction —
|
|
various derived classes of Value
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
BasicBlock — another derived of Value, represents an LLVM basic block
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Builder — used for creating instructions, wraps LLVM IRBuilder helper
|
|
class
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
ModuleProvider — 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 — represents an execution engine (which can be an
|
|
either an interpreter or a JIT)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
TargetData — 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 — represents an LLVM pass manager
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
FunctionPassManager — 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>. 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>__doc__</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 <em>not</em> 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>
|
|
An iterable that yields <tt>GlobalVariable</tt> objects, that represent
|
|
the global variables of the module.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>functions</tt> [read-only]
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
An iterable that yields <tt>Function</tt> objects, that represent functions
|
|
in the module.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
<div class="title">Methods</div><dl>
|
|
<dt>
|
|
<tt>add_type_name(name, ty)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Add an alias (typedef) for the type <tt>ty</tt> with the name <tt>name</tt>.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>delete_type_name(name)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Delete an alias with the name <tt>name</tt>.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>add_global_variable(ty, name)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Add a global variable of the type <tt>ty</tt> with the name <tt>name</tt>.
|
|
Returns a <tt>GlobalVariable</tt> object.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>get_global_variable_named(name)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Get a <tt>GlobalVariable</tt> object corresponding to the global
|
|
variable with the name <tt>name</tt>. Raises <tt>LLVMException</tt> if such a
|
|
variable does not exist.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>add_function(ty, name)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Add a function named <tt>name</tt> with the function type <tt>ty</tt>. <tt>ty</tt> must
|
|
of an object of type <tt>FunctionType</tt>.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>get_function_named(name)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Get a <tt>Function</tt> object corresponding to the function with the name
|
|
<tt>name</tt>. Raises <tt>LLVMException</tt> if such a function does not exist.
|
|
</p>
|
|
</dd>
|
|
<dt>
|
|
<tt>verify()</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
Verify 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. “ <tt>print module_obj</tt> ” 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 <tt>Type). `addrspc</tt>
|
|
is an integer that represents the address space of the pointer (see
|
|
LLVM docs / ask on llvm-dev for more info).
|
|
</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 “type” 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 — 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
|
|
— 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>
|
|
<p>The following constructors (static methods) can be used to create
|
|
constants:</p>
|
|
<div class="tableblock">
|
|
<a id="constctors"></a>
|
|
<table rules="all"
|
|
frame="border"
|
|
cellspacing="0" cellpadding="4">
|
|
<col width="200" />
|
|
<col width="600" />
|
|
<thead>
|
|
<tr>
|
|
<th align="left">
|
|
Constructor Method
|
|
</th>
|
|
<th align="left">
|
|
What It Creates
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr>
|
|
<td align="left">
|
|
<tt>null(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
A null value (all zeros) of type <tt>ty</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>all_ones(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
All 1's value of type <tt>ty</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>undef(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
An “undefined” value of type <tt>ty</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>int(ty, value)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Integer of type <tt>ty</tt>, with value <tt>value</tt> (a Python int or long)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>int_signextend(ty, value)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Integer of signed type <tt>ty</tt> (use for signed types)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>real(ty, value)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Floating point value of type <tt>ty</tt>, with value <tt>value</tt> (a Python float)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>stringz(value)</tt>
|
|
</td>
|
|
<td align="left">
|
|
A null-terminated string. <tt>value</tt> is a Python string
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>string(value)</tt>
|
|
</td>
|
|
<td align="left">
|
|
As <tt>string(ty)</tt>, but not null terminated
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>array(ty, consts)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Array of type <tt>ty</tt>, initialized with <tt>consts</tt> (an iterable yielding <tt>Constant</tt> objects of the appropriate type)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>struct(ty, consts)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Struct (unpacked) of type <tt>ty</tt>, initialized with <tt>consts</tt> (an iterable yielding <tt>Constant</tt> objects of the appropriate type)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>packed_struct(ty, consts)</tt>
|
|
</td>
|
|
<td align="left">
|
|
As <tt>struct(ty, consts)</tt> but packed
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>vector(consts)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Vector, initialized with <tt>consts</tt> (an iterable yielding <tt>Constant</tt> objects of the appropriate type)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>sizeof(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Constant value representing the sizeof the type <tt>ty</tt>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p>The following operations are available:</p>
|
|
<div class="tableblock">
|
|
<a id="constops"></a>
|
|
<table rules="all"
|
|
frame="border"
|
|
cellspacing="0" cellpadding="4">
|
|
<col width="200" />
|
|
<col width="600" />
|
|
<thead>
|
|
<tr>
|
|
<th align="left">
|
|
Method
|
|
</th>
|
|
<th align="left">
|
|
Operation
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.neg()</tt>
|
|
</td>
|
|
<td align="left">
|
|
negation, same as <tt>0 - k</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.not_()</tt>
|
|
</td>
|
|
<td align="left">
|
|
1's complement of <tt>k</tt>. Note trailing underscore.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.add(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
<tt>k + k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.sub(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
<tt>k - k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.mul(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
<tt>k * k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.udiv(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Quotient of unsigned division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.sdiv(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Quotient of signed division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.fdiv(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Quotient of floating point division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.urem(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Reminder of unsigned division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.srem(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Reminder of signed division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.frem(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Reminder of floating point division of <tt>k</tt> with <tt>k2</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.and_(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Bitwise and of <tt>k</tt> and <tt>k2</tt>. Note trailing underscore.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.or_(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Bitwise or of <tt>k</tt> and <tt>k2</tt>. Note trailing underscore.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.xor(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Bitwise exclusive-or of <tt>k</tt> and <tt>k2</tt>.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.icmp(ipred, k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Compare <tt>k</tt> with <tt>k2</tt> using the predicate <tt>ipred</tt>. See table <a href="#ipred">below</a> for list of predicates for integer operands.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.fcmp(rpred, k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Compare <tt>k</tt> with <tt>k2</tt> using the predicate <tt>rpred</tt>. See table <a href="#rpred">below</a> for list of predicates for real operands.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.shl(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Shift <tt>k</tt> left by <tt>k2</tt> bits.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.lshr(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Shift <tt>k</tt> logically right by <tt>k2</tt> bits (new bits are 0s).
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.ashr(k2)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Shift <tt>k</tt> arithmetically right by <tt>k2</tt> bits (new bits are same as previous sign bit).
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.gep(indices)</tt>
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.trunc(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Truncate <tt>k</tt> to a type <tt>ty</tt> of lower bitwidth.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.sext(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Sign extend <tt>k</tt> to a type <tt>ty</tt> of higher bitwidth, while extending the sign bit.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>k.zext(ty)</tt>
|
|
</td>
|
|
<td align="left">
|
|
Sign extend <tt>k</tt> to a type <tt>ty</tt> of higher bitwidth, all new bits are 0s.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
fptrunc
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
fpext
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
uitofp
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
sitofp
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
fptoui
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
fptosi
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
ptrtoint
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
inttoptr
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
bitcast
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
select
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
extract_element
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
insert_element
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
shuffle_vector
|
|
</td>
|
|
<td align="left">
|
|
TODO
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p><a id="ipred"></a>Predicates for use with <tt>icmp</tt> instruction are listed below. All
|
|
of these are integer constants defined in the <tt>llvm.core</tt> module.</p>
|
|
<div class="tableblock">
|
|
<table rules="all"
|
|
frame="border"
|
|
cellspacing="0" cellpadding="4">
|
|
<col width="200" />
|
|
<col width="600" />
|
|
<thead>
|
|
<tr>
|
|
<th align="left">
|
|
Value
|
|
</th>
|
|
<th align="left">
|
|
Meaning
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_EQ</tt>
|
|
</td>
|
|
<td align="left">
|
|
Equality
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_NE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Inequality
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_UGT</tt>
|
|
</td>
|
|
<td align="left">
|
|
Unsigned greater than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_UGE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Unsigned greater than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_ULT</tt>
|
|
</td>
|
|
<td align="left">
|
|
Unsigned less than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_ULE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Unsigned less than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_SGT</tt>
|
|
</td>
|
|
<td align="left">
|
|
Signed greater than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_SGE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Signed greater than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_SLT</tt>
|
|
</td>
|
|
<td align="left">
|
|
Signed less than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>IPRED_SLE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Signed less than or equal
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p><a id="rpred"></a>Predicates for use with <tt>fcmp</tt> instruction are listed below. All
|
|
of these are integer constants defined in the <tt>llvm.core</tt> module.</p>
|
|
<div class="tableblock">
|
|
<table rules="all"
|
|
frame="border"
|
|
cellspacing="0" cellpadding="4">
|
|
<col width="200" />
|
|
<col width="600" />
|
|
<thead>
|
|
<tr>
|
|
<th align="left">
|
|
Value
|
|
</th>
|
|
<th align="left">
|
|
Meaning
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_FALSE</tt>
|
|
</td>
|
|
<td align="left">
|
|
Always false
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_OEQ</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_OGT</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and greater than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_OGE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and greater than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_OLT</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and less than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_OLE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and less than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_ONE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered and operands are unequal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_ORD</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if ordered (no NaNs)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_UNO</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered: <tt>isnan(X) | isnan(Y)</tt>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_UEQ</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_UGT</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered or greater than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_UGE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered, greater than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_ULT</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered, or less than
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_ULE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered, less than or equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_UNE</tt>
|
|
</td>
|
|
<td align="left">
|
|
True if unordered or not equal
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">
|
|
<tt>RPRED_TRUE </tt>
|
|
</td>
|
|
<td align="left">
|
|
Always true
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="title">llvm.core.Constant</div>
|
|
<div class="exampleblock-content">
|
|
<div class="title">Base Class</div><ul>
|
|
<li>
|
|
<p>
|
|
<tt>llvm.core.Value</tt>
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
<div class="title">Static Constructors</div>
|
|
<p>See table of constructors <a href="#constctors">above</a> for full list.</p>
|
|
<div class="title">Methods</div>
|
|
<p>See table of operations <a href="#constops">above</a> for full list. There are no other
|
|
methods.</p>
|
|
</div></div>
|
|
<h3>TypeHandle (llvm.core)</h3>
|
|
<p>TypeHandle objects are used to create recursive types, like this linked
|
|
list node structure in C:</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">struct</span></span> node
|
|
<span style="color: #FF0000">{</span>
|
|
<span style="color: #009900">int</span> data<span style="color: #990000">;</span>
|
|
<span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> node <span style="color: #990000">*</span>next<span style="color: #990000">;</span>
|
|
<span style="color: #FF0000">}</span><span style="color: #990000">;</span>
|
|
</tt></pre></div></div>
|
|
<p>This can be realized in llvm-py like this:</p>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre><tt>#!/usr/bin/env python
|
|
|
|
from llvm.core import *
|
|
|
|
# create a type handle object
|
|
th = TypeHandle.new(Type.opaque())
|
|
|
|
# create the struct with an opaque* instead of self*
|
|
ts = Type.struct([ Type.int(), Type.pointer(th.type) ])
|
|
|
|
# unify the types
|
|
th.type.refine(ts)
|
|
|
|
# create a module, and add a "typedef"
|
|
m = Module.new('mod1')
|
|
m.add_type_name("struct.node", th.type)
|
|
|
|
# show what we created
|
|
print m</tt></pre>
|
|
</div></div>
|
|
<div class="listingblock">
|
|
<div class="content"></div></div>
|
|
<p>which gives the output:</p>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre><tt>; ModuleID = 'mod1'
|
|
%struct.node = type { i32, %struct.node* }</tt></pre>
|
|
</div></div>
|
|
<p>For more details on what is going on here, please refer the LLVM
|
|
Programmer's Manual section
|
|
<a href="http://llvm.org/docs/ProgrammersManual.html#TypeResolve">"LLVM Type
|
|
Resolution"</a>. The TypeHandle class of llvm-py corresponds to
|
|
<a href="http://www.llvm.org/doxygen/classllvm_1_1PATypeHolder.html"><tt>llvm::PATypeHolder</tt></a>
|
|
in C++. The above example is available as
|
|
<a href="http://code.google.com/p/llvm-py/source/browse/trunk/test/typehandle.py">test/typehandle.py</a>
|
|
in the source distribution.</p>
|
|
<div class="exampleblock">
|
|
<div class="title">llvm.core.TypeHandle</div>
|
|
<div class="exampleblock-content">
|
|
<div class="title">Static Constructors</div><dl>
|
|
<dt>
|
|
<tt>new(abstract_ty)</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
create a new <tt>TypeHandle</tt> instance, which holds a reference to the
|
|
given abstract type <tt>abstract_ty</tt>. Typically, the abstract type used
|
|
is <tt>Type.opaque()</tt>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
<div class="title">Properties</div><dl>
|
|
<dt>
|
|
<tt>type</tt>
|
|
</dt>
|
|
<dd>
|
|
<p>
|
|
returns the contained type. Typically the <tt>refine</tt> method is called
|
|
on the returned type.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
</div></div>
|
|
<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><a id="examples"></a>Annotated Examples</h2>
|
|
<div class="sectionbody">
|
|
<h3>A Simple Function</h3>
|
|
<p>Let's create a (LLVM) module containing a single function, corresponding
|
|
to the <tt>C</tt> function:</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">int</span> <span style="font-weight: bold"><span style="color: #000000">sum</span></span><span style="color: #990000">(</span><span style="color: #009900">int</span> a<span style="color: #990000">,</span> <span style="color: #009900">int</span> b<span style="color: #990000">)</span>
|
|
<span style="color: #FF0000">{</span>
|
|
<span style="font-weight: bold"><span style="color: #0000FF">return</span></span> a <span style="color: #990000">+</span> b<span style="color: #990000">;</span>
|
|
<span style="color: #FF0000">}</span>
|
|
</tt></pre></div></div>
|
|
<p>Here's how it looks like:</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"># Import the llvm-py modules.</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 an (empty) 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>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># All the types involved here are "int"s. This type is represented</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># by an object of the llvm.core.Type class:</span></span>
|
|
ty<span style="color: #009900">_</span>int <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"># by default 32 bits</span></span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># We need to represent the class of functions that accept two integers</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># and return an integer. This is represented by an object of the</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># function type (llvm.core.FunctionType):</span></span>
|
|
ty<span style="color: #009900">_</span>func <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>ty<span style="color: #009900">_</span>int<span style="color: #990000">,</span> <span style="color: #990000">[</span>ty<span style="color: #009900">_</span>int<span style="color: #990000">,</span> ty<span style="color: #009900">_</span>int<span style="color: #990000">])</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Now we need a function named 'sum' of this type. Functions are not</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># free-standing (in llvm-py); it needs to be contained in a module.</span></span>
|
|
f<span style="color: #009900">_</span>sum <span style="color: #990000">=</span> my<span style="color: #009900">_</span>module<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">add_function</span></span><span style="color: #990000">(</span>ty<span style="color: #009900">_</span>func<span style="color: #990000">,</span> <span style="color: #FF0000">"sum"</span><span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Let's name the function arguments as 'a' and 'b'.</span></span>
|
|
f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">0</span><span style="color: #990000">].</span>name <span style="color: #990000">=</span> <span style="color: #FF0000">"a"</span>
|
|
f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">1</span><span style="color: #990000">].</span>name <span style="color: #990000">=</span> <span style="color: #FF0000">"b"</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Our function needs a "basic block" -- a set of instructions that</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># end with a terminator (like return, branch etc.). By convention</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># the first block is called "entry".</span></span>
|
|
bb <span style="color: #990000">=</span> f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">append_basic_block</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"entry"</span><span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Let's add instructions into the block. For this, we need an</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># instruction builder:</span></span>
|
|
builder <span style="color: #990000">=</span> <span style="color: #009900">Builder</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">new</span></span><span style="color: #990000">(</span>bb<span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># OK, now for the instructions themselves. We'll create an add</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># instruction that returns the sum as a value, which we'll use</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># a ret instruction to return.</span></span>
|
|
tmp <span style="color: #990000">=</span> builder<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">add</span></span><span style="color: #990000">(</span>f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">0</span><span style="color: #990000">],</span> f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">1</span><span style="color: #990000">],</span> <span style="color: #FF0000">"tmp"</span><span style="color: #990000">)</span>
|
|
builder<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">ret</span></span><span style="color: #990000">(</span>tmp<span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># We've completed the definition now! Let's see the LLVM assembly</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># language representation of what we've created:</span></span>
|
|
<span style="font-weight: bold"><span style="color: #0000FF">print</span></span> my<span style="color: #009900">_</span>module
|
|
</tt></pre></div></div>
|
|
<p>Here is the output:</p>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre><tt>; ModuleID = 'my_module'
|
|
|
|
define i32 @sum(i32 %a, i32 %b) {
|
|
entry:
|
|
%tmp = add i32 %a, %b ; <i32> [#uses=1]
|
|
ret i32 %tmp
|
|
}</tt></pre>
|
|
</div></div>
|
|
<h3>Adding JIT Compilation</h3>
|
|
<p>Let's compile this function in-memory and run it.</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"># Import the llvm-py modules.</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-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-style: italic"><span style="color: #9A1900"># new import: ee = Execution Engine</span></span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Create a module, as in the previous example.</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>
|
|
ty<span style="color: #009900">_</span>int <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"># by default 32 bits</span></span>
|
|
ty<span style="color: #009900">_</span>func <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>ty<span style="color: #009900">_</span>int<span style="color: #990000">,</span> <span style="color: #990000">[</span>ty<span style="color: #009900">_</span>int<span style="color: #990000">,</span> ty<span style="color: #009900">_</span>int<span style="color: #990000">])</span>
|
|
f<span style="color: #009900">_</span>sum <span style="color: #990000">=</span> my<span style="color: #009900">_</span>module<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">add_function</span></span><span style="color: #990000">(</span>ty<span style="color: #009900">_</span>func<span style="color: #990000">,</span> <span style="color: #FF0000">"sum"</span><span style="color: #990000">)</span>
|
|
f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">0</span><span style="color: #990000">].</span>name <span style="color: #990000">=</span> <span style="color: #FF0000">"a"</span>
|
|
f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">1</span><span style="color: #990000">].</span>name <span style="color: #990000">=</span> <span style="color: #FF0000">"b"</span>
|
|
bb <span style="color: #990000">=</span> f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">append_basic_block</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"entry"</span><span style="color: #990000">)</span>
|
|
builder <span style="color: #990000">=</span> <span style="color: #009900">Builder</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">new</span></span><span style="color: #990000">(</span>bb<span style="color: #990000">)</span>
|
|
tmp <span style="color: #990000">=</span> builder<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">add</span></span><span style="color: #990000">(</span>f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">0</span><span style="color: #990000">],</span> f<span style="color: #009900">_</span>sum<span style="color: #990000">.</span>args<span style="color: #990000">[</span><span style="color: #993399">1</span><span style="color: #990000">],</span> <span style="color: #FF0000">"tmp"</span><span style="color: #990000">)</span>
|
|
builder<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">ret</span></span><span style="color: #990000">(</span>tmp<span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Create a module provider object first. Modules can come from</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># in-memory IRs like what we created now, or from bitcode (.bc)</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># files. The module provider abstracts this detail.</span></span>
|
|
mp <span style="color: #990000">=</span> <span style="color: #009900">ModuleProvider</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">new</span></span><span style="color: #990000">(</span>my<span style="color: #009900">_</span>module<span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># Create an execution engine object. This will create a JIT compiler</span></span>
|
|
<span style="font-style: italic"><span style="color: #9A1900"># on platforms that support it, or an interpreter otherwise.</span></span>
|
|
ee <span style="color: #990000">=</span> <span style="color: #009900">ExecutionEngine</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">new</span></span><span style="color: #990000">(</span>mp<span style="color: #990000">)</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># The arguments needs to be passed as "GenericValue" objects.</span></span>
|
|
arg1 <span style="color: #990000">=</span> <span style="color: #009900">GenericValue</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span>ty<span style="color: #009900">_</span>int<span style="color: #990000">,</span> <span style="color: #993399">100</span><span style="color: #990000">)</span>
|
|
arg2 <span style="color: #990000">=</span> <span style="color: #009900">GenericValue</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">int</span></span><span style="color: #990000">(</span>ty<span style="color: #009900">_</span>int<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"># Now let's compile and run!</span></span>
|
|
retval <span style="color: #990000">=</span> ee<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">run_function</span></span><span style="color: #990000">(</span>f<span style="color: #009900">_</span>sum<span style="color: #990000">,</span> <span style="color: #990000">[</span>arg1<span style="color: #990000">,</span> arg2<span style="color: #990000">])</span>
|
|
|
|
<span style="font-style: italic"><span style="color: #9A1900"># The return value is also GenericValue. Let's print it.</span></span>
|
|
<span style="font-weight: bold"><span style="color: #0000FF">print</span></span> <span style="color: #FF0000">"returned"</span><span style="color: #990000">,</span> retval<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">as_int</span></span><span style="color: #990000">()</span>
|
|
</tt></pre></div></div>
|
|
<p>And here's the output:</p>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre><tt>returned 142</tt></pre>
|
|
</div></div>
|
|
</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 the
|
|
Google code hosting service, at
|
|
<a href="http://code.google.com/p/llvm-py/">http://code.google.com/p/llvm-py/</a>.
|
|
It 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 (pre-)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 © Mahadevan R. Generated with <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.
|
|
Last updated 31-Jul-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"));
|
|
var pageTracker = _gat._getTracker("UA-4519056-2");
|
|
pageTracker._initData();
|
|
pageTracker._trackPageview();
|
|
</script>
|
|
</body>
|
|
</html>
|