git-svn-id: http://llvm-py.googlecode.com/svn/trunk@36 8d1e9007-1d4e-0410-b67e-1979fd6579aa
246 lines
20 KiB
HTML
246 lines
20 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" />
|
|
<title>Examples and LLVM Tutorials - 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="layout-content">
|
|
<div id="header">
|
|
<h1>Examples and LLVM Tutorials</h1>
|
|
</div>
|
|
<h2>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>LLVM Tutorials</h2>
|
|
<div class="sectionbody">
|
|
<p>The <a href="http://www.llvm.org/docs/tutorial/">LLVM tutorials</a> have been
|
|
ported to llvm-py. Below are the links to the original LLVM tutorial and
|
|
the corresponding Python code using llvm-py:</p>
|
|
<div class="title">Simple JIT Tutorials</div>
|
|
<p>(These were contributed by Sebastien Binet; thanks!)</p>
|
|
<ol>
|
|
<li>
|
|
<p>
|
|
A First Function
|
|
<a href="http://www.llvm.org/docs/tutorial/JITTutorial1.html">LLVM</a>
|
|
<a href="examples/JITTutorial1.html">llvm-py</a>
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
A More Complicated Function
|
|
<a href="http://www.llvm.org/docs/tutorial/JITTutorial2.html">LLVM</a>
|
|
<a href="examples/JITTutorial2.html">llvm-py</a>
|
|
</p>
|
|
</li>
|
|
</ol>
|
|
<div class="title">Kaleidoscope: Implementing a Language with LLVM</div><ol>
|
|
<li>
|
|
<p>
|
|
Tutorial Introduction and the Lexer (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Implementing a Parser and AST (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Implementing Code Generation to LLVM IR (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Adding JIT and Optimizer Support (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Extending the language: control flow (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Extending the language: user-defined operators (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Extending the language: mutable variables / SSA construction (TODO)
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
Conclusion and other useful LLVM tidbits (TODO)
|
|
</p>
|
|
</li>
|
|
</ol>
|
|
</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 08-Sep-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>
|