diff --git a/www/makeweb.py b/www/makeweb.py index de955b3..f17df8a 100755 --- a/www/makeweb.py +++ b/www/makeweb.py @@ -6,7 +6,7 @@ from string import Template from optparse import OptionParser # files in src dir that should not be copied to web dir -SKIP_FILES = [ 'layout.conf', '.svn', 'instrset.inc' ] +SKIP_FILES = [ 'layout.conf', '.svn', 'instrset.inc', 'example.inc' ] # asciidoc command line ASCIIDOC = 'asciidoc --unsafe --conf-file=${srcdir}/layout.conf -a icons -o ${outfile} ${infile}' diff --git a/www/src/example.inc b/www/src/example.inc new file mode 100644 index 0000000..08b2a2c --- /dev/null +++ b/www/src/example.inc @@ -0,0 +1,132 @@ + +A Simple Function +~~~~~~~~~~~~~~~~~ + +Let's create a module containing a single function, corresponding to the +`C` function: + +[C] +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +int sum(int a, int b) +{ + return a + b; +} +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here's how it looks like: + +[python] +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#!/usr/bin/env python + +# Import the llvm-py modules. +from llvm import * +from llvm.core import * + +# Create a module. +my_module = Module.new('my_module') + +# All the types involved here are "int"s. This type is represented +# by an object of the llvm.core.Type class: +ty_int = Type.int() # by default 32 bits + +# We need to represent the class of functions that accept two integers +# and return an integer. This is represented by an object of the +# function type (llvm.core.FunctionType): +ty_func = Type.function(ty_int, [ty_int, ty_int]) + +# Now we need a function named 'sum' of this type. Functions are not +# free-standing (in llvm-py); it needs to be contained in a module. +f_sum = my_module.add_function(ty_func, "sum") + +# Let's name the function arguments as 'a' and 'b'. +f_sum.args[0].name = "a" +f_sum.args[1].name = "b" + +# Our function needs a "basic block" -- a set of instructions that +# end with a terminator (like return, branch etc.). By convention +# the first block is called "entry". +bb = f_sum.append_basic_block("entry") + +# Let's add instructions into the block. For this, we need an +# instruction builder: +builder = Builder.new(bb) + +# OK, now for the instructions themselves. We'll create an add +# instruction that returns the sum as a value, which we'll use +# a ret instruction to return. +tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp") +builder.ret(tmp) + +# We've completed the definition now! Let's see the LLVM assembly +# language representation of what we've created: +print my_module +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is the output: + +----------------------------------------------------------------------- +; ModuleID = 'my_module' + +define i32 @sum(i32 %a, i32 %b) { +entry: + %tmp = add i32 %a, %b ; [#uses=1] + ret i32 %tmp +} +----------------------------------------------------------------------- + + +Adding JIT Compilation +~~~~~~~~~~~~~~~~~~~~~~ + +Let's compile this function in-memory and run it. + +[python] +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#!/usr/bin/env python + +# Import the llvm-py modules. +from llvm import * +from llvm.core import * +from llvm.ee import * # new import: ee = Execution Engine + +# Create a module, as in the previous example. +my_module = Module.new('my_module') +ty_int = Type.int() # by default 32 bits +ty_func = Type.function(ty_int, [ty_int, ty_int]) +f_sum = my_module.add_function(ty_func, "sum") +f_sum.args[0].name = "a" +f_sum.args[1].name = "b" +bb = f_sum.append_basic_block("entry") +builder = Builder.new(bb) +tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp") +builder.ret(tmp) + +# Create a module provider object first. Modules can come from +# in-memory IRs like what we created now, or from bitcode (.bc) +# files. The module provider abstracts this detail. +mp = ModuleProvider.new(my_module) + +# Create an execution engine object. This will create a JIT compiler +# on platforms that support it, or an interpreter otherwise. +ee = ExecutionEngine.new(mp) + +# The arguments needs to be passed as "GenericValue" objects. +arg1 = GenericValue.int(ty_int, 100) +arg2 = GenericValue.int(ty_int, 42) + +# Now let's compile and run! +retval = ee.run_function(f_sum, [arg1, arg2]) + +# The return value is also GenericValue. Let's print it. +print "returned", retval.as_int() +source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +And here's the output: + +----------------------------------------------------------------------- +returned 142 +----------------------------------------------------------------------- + +That was easy, right?! + diff --git a/www/src/examples.txt b/www/src/examples.txt index 9eb17e0..5a33cc4 100644 --- a/www/src/examples.txt +++ b/www/src/examples.txt @@ -1,25 +1,5 @@ Examples ======== -Here's an example: - -[python] -source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -include::../../test/example.py[] -source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -which gives this output: - ------------------------------------------------------------------------ -; ModuleID = 'my_module' - -define i32 @foobar(double %arg1, double %arg2) { -entry: - %temp1 = add double %arg1, %arg2 ; [#uses=1] - %temp2 = sub double %temp1, 1.000000e+00 ; [#uses=1] - %temp3 = fptoui double %temp2 to i32 ; [#uses=1] - ret i32 %temp3 -} ------------------------------------------------------------------------ - +include::example.inc[] diff --git a/www/src/layout.conf b/www/src/layout.conf index 768f832..8bc2972 100644 --- a/www/src/layout.conf +++ b/www/src/layout.conf @@ -68,16 +68,16 @@ endif::toc[]
»About
-
- ifdef::toc[] -
+
Table of Contents
endif::toc[] +
+ [footer] diff --git a/www/web/contribute.html b/www/web/contribute.html index 65387c0..52d17a0 100644 --- a/www/web/contribute.html +++ b/www/web/contribute.html @@ -124,7 +124,7 @@ Improve tests.
diff --git a/www/web/download.html b/www/web/download.html index a73cc99..cbbf721 100644 --- a/www/web/download.html +++ b/www/web/download.html @@ -149,7 +149,7 @@ package.

diff --git a/www/web/examples.html b/www/web/examples.html index 648bce5..aef76ef 100644 --- a/www/web/examples.html +++ b/www/web/examples.html @@ -31,9 +31,20 @@ -
-
-

Here's an example:

+

A Simple Function

+

Let's create a module containing a single function, corresponding to the +C function:

+
+
+
int sum(int a, int b)
+{
+    return a + b;
+}
+
+

Here's how it looks like:

#!/usr/bin/env python
 
+# Import the llvm-py modules.
+from llvm import *
 from llvm.core import *
 
-## create a module
-module = Module.new("my_module")
+# Create a module.
+my_module = Module.new('my_module')
 
-## create a function type taking two doubles and returning a (32-bit) integer
-ty_double = Type.double()
-ty_int    = Type.int()
-ty_func   = Type.function( ty_int, [ ty_double, ty_double ] )
+# All the types involved here are "int"s. This type is represented
+# by an object of the llvm.core.Type class:
+ty_int = Type.int()   # by default 32 bits
 
-## create a function of this type
-func      = Function.new( module, ty_func, "foobar" )
+# We need to represent the class of functions that accept two integers
+# and return an integer. This is represented by an object of the
+# function type (llvm.core.FunctionType):
+ty_func = Type.function(ty_int, [ty_int, ty_int])
 
-# name function args
-func.args[0].name = "arg1"
-func.args[1].name = "arg2"
+# Now we need a function named 'sum' of this type. Functions are not
+# free-standing (in llvm-py); it needs to be contained in a module.
+f_sum = my_module.add_function(ty_func, "sum")
 
-## implement the function
+# Let's name the function arguments as 'a' and 'b'.
+f_sum.args[0].name = "a"
+f_sum.args[1].name = "b"
 
-# add a basic block
-entry = func.append_basic_block("entry")
+# Our function needs a "basic block" -- a set of instructions that
+# end with a terminator (like return, branch etc.). By convention
+# the first block is called "entry".
+bb = f_sum.append_basic_block("entry")
 
-# create an llvm::IRBuilder
-builder = Builder.new(entry)
+# Let's add instructions into the block. For this, we need an
+# instruction builder:
+builder = Builder.new(bb)
 
-# add two args into tmp1
-tmp1 = builder.add(func.args[0], func.args[1], "tmp1")
+# OK, now for the instructions themselves. We'll create an add
+# instruction that returns the sum as a value, which we'll use
+# a ret instruction to return.
+tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
+builder.ret(tmp)
 
-# sub `1' from that
-one = Constant.real( ty_double, 1.0 )
-tmp2 = builder.sub(tmp1, one, "tmp2")
-
-# convert to integer
-tmp3 = builder.fptoui(tmp2, ty_int, "tmp3")
-
-# return it
-builder.ret(tmp3)
-
-# dump the module to see the llvm "assembly" code
-print module
+# We've completed the definition now! Let's see the LLVM assembly
+# language representation of what we've created:
+print my_module
 
-

which gives this output:

+

Here is the output:

; ModuleID = 'my_module'
 
-define i32 @foobar(double %arg1, double %arg2) {
+define i32 @sum(i32 %a, i32 %b) {
 entry:
-        %temp1 = add double %arg1, %arg2                ; <double> [#uses=1]
-        %temp2 = sub double %temp1, 1.000000e+00                ; <double> [#uses=1]
-        %temp3 = fptoui double %temp2 to i32            ; <i32> [#uses=1]
-        ret i32 %temp3
+        %tmp = add i32 %a, %b           ; <i32> [#uses=1]
+        ret i32 %tmp
 }
-
-
+

Adding JIT Compilation

+

Let's compile this function in-memory and run it.

+
+
+
#!/usr/bin/env python
+
+# Import the llvm-py modules.
+from llvm import *
+from llvm.core import *
+from llvm.ee import *          # new import: ee = Execution Engine
+
+# Create a module, as in the previous example.
+my_module = Module.new('my_module')
+ty_int = Type.int()   # by default 32 bits
+ty_func = Type.function(ty_int, [ty_int, ty_int])
+f_sum = my_module.add_function(ty_func, "sum")
+f_sum.args[0].name = "a"
+f_sum.args[1].name = "b"
+bb = f_sum.append_basic_block("entry")
+builder = Builder.new(bb)
+tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
+builder.ret(tmp)
+
+# Create a module provider object first. Modules can come from
+# in-memory IRs like what we created now, or from bitcode (.bc)
+# files. The module provider abstracts this detail.
+mp = ModuleProvider.new(my_module)
+
+# Create an execution engine object. This will create a JIT compiler
+# on platforms that support it, or an interpreter otherwise.
+ee = ExecutionEngine.new(mp)
+
+# The arguments needs to be passed as "GenericValue" objects.
+arg1 = GenericValue.int(ty_int, 100)
+arg2 = GenericValue.int(ty_int, 42)
+
+# Now let's compile and run!
+retval = ee.run_function(f_sum, [arg1, arg2])
+
+# The return value is also GenericValue. Let's print it.
+print "returned", retval.as_int()
+
+

And here's the output:

+
+
+
returned 142
+
+

That was easy, right?!

diff --git a/www/web/index.html b/www/web/index.html index 3da18aa..ae154fa 100644 --- a/www/web/index.html +++ b/www/web/index.html @@ -76,7 +76,7 @@ miss any specific LLVM API.

diff --git a/www/web/license.html b/www/web/license.html index 66eb017..9c4b646 100644 --- a/www/web/license.html +++ b/www/web/license.html @@ -74,7 +74,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/www/web/userguide.html b/www/web/userguide.html index e6b9383..fe86bab 100644 --- a/www/web/userguide.html +++ b/www/web/userguide.html @@ -33,14 +33,14 @@ window.onload = function(){generateToc(2)}
»About
+
+
Table of Contents
+ +
-
-
Table of Contents
- -
@@ -48,8 +48,11 @@ window.onload = function(){generateToc(2)} Note -This document is updated frequently (last updated on 24-Jun-2008). -Check back often. + +

This document is updated frequently (last updated on 25-Jun-2008). +Check back often.

+

You might wish to look over the examples first.

+

llvm-py provides Python bindings for LLVM. This document explains how @@ -110,7 +113,7 @@ LLVM, either installed or built

On debian-based systems, the first three can be installed with the -command `sudo apt-get install gcc g++ python python-dev'. Note that +command sudo apt-get install gcc g++ python python-dev. Note that ubuntu repository has an old version of llvm (1.8) which will not work with llvm-py.

It does not matter which compiler LLVM itself was built with (g++, @@ -299,12 +302,12 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->

/* compute sum of 1..n */
-unsigned sum(unsigned n)
+unsigned sum(unsigned n)
 {
   if (n == 0)
     return 0;
   else
-    return n + sum(n-1);
+    return n + sum(n-1);
 }
 

The corresponding LLVM assembly:

@@ -503,7 +506,7 @@ cellspacing="0" cellpadding="4">

Intrinsics (instructions that start with llvm.) are not yet available in llvm-py.

Modules

-

Modules, in the LLVM IR, are similar to a single C language source +

Modules, in the LLVM IR, are similar to a single C language source file (.c file). A module contains:

  • @@ -537,7 +540,7 @@ describes all the available passes, and what they do.

    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.

    -

    There is a LLVM binary called opt, +

    There is an LLVM binary called opt, 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 opt. (Although llvm-py does not allow you to @@ -557,9 +560,9 @@ any stage, and perform any transforms on it as you like.)

    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.

    -

    Out of the 6 modules, one is an "extension" module (i.e., it's written -in C), and another one is a private utility module, which leaves 4 -public modules. These are:

    +

    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:

    • @@ -587,7 +590,7 @@ Python constructs are used (deliberately) — property() and property decorators are probably the most exotic animals around. All classes are -the "new style" classes. The APIs are designed to be navigable (and +"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.

      Here is a quick overview of the contents of each package:

      @@ -717,8 +720,8 @@ constants PASS_* that represent various passes
    A note on the 'import'ing of these modules

    Pythonically, modules are imported with the statement "import -llvm.core" and not "from llvm.core import *". However, you might find -it more convenient to import llvm-py modules thus:

    +llvm.core". However, you might find it more convenient to import +llvm-py modules thus:

    Tip -Python-style documentation strings (doc) are present in +Python-style documentation strings (__doc__) are present in llvm-py. You can use the help() of the interactive Python interpreter or the object? of IPython to get online help. (Note: not complete yet!) @@ -756,9 +759,9 @@ http://www.gnu.org/software/src-highlite --> from llvm.core import * # create a module -my_module = Module.new('my_module') +my_module = Module.new('my_module')
    -

    The constructor of the Module class should not be used to instantiate +

    The constructor of the Module class should not be used to instantiate a Module object. This is a common feature for all llvm-py classes.

    @@ -1290,8 +1293,8 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
    assert Type.int().kind == TYPE_INTEGER
    -assert Type.void().kind == TYPE_VOID
    +
    assert Type.int().kind == TYPE_INTEGER
    +assert Type.void().kind == TYPE_VOID
     
    @@ -1390,11 +1393,11 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
    func_type = Type.function( Type.int(), [ Type.int(), Type.int() ] )
    +
    func_type = Type.function( Type.int(), [ Type.int(), Type.int() ] )
     for arg in func_type.args:
         assert arg.kind == TYPE_INTEGER
    -    assert arg == Type.int()
    -assert func_type.arg_count == len(func_type.args)
    +    assert arg == Type.int()
    +assert func_type.arg_count == len(func_type.args)
     
    @@ -1440,11 +1443,11 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
    struct_type = Type.struct( [ Type.int(), Type.int() ] )
    +
    struct_type = Type.struct( [ Type.int(), Type.int() ] )
     for elem in struct_type.elements:
         assert elem.kind == TYPE_INTEGER
    -    assert elem == Type.int()
    -assert struct_type.element_count == len(struct_type.elements)
    +    assert elem == Type.int()
    +assert struct_type.element_count == len(struct_type.elements)
     
    @@ -1553,35 +1556,35 @@ http://www.gnu.org/software/src-highlite -->
    #!/usr/bin/env python
     
     # integers
    -int_ty      = Type.int()
    -bool_ty     = Type.int(1)
    -int_64bit   = Type.int(64)
    +int_ty      = Type.int()
    +bool_ty     = Type.int(1)
    +int_64bit   = Type.int(64)
     
     # floats
    -sprec_real  = Type.float()
    -dprec_real  = Type.double()
    +sprec_real  = Type.float()
    +dprec_real  = Type.double()
     
     # arrays and vectors
    -intar_ty    = Type.array( int_ty, 10 )     # "typedef int intar_ty[10];"
    -twodim      = Type.array( intar_ty , 10 )  # "typedef int twodim[10][10];"
    -vec         = Type.array( int_ty, 10 )
    +intar_ty    = Type.array( int_ty, 10 )     # "typedef int intar_ty[10];"
    +twodim      = Type.array( intar_ty , 10 )  # "typedef int twodim[10][10];"
    +vec         = Type.array( int_ty, 10 )
     
     # structures
    -s1_ty       = Type.struct( [ int_ty, sprec_real ] )
    +s1_ty       = Type.struct( [ int_ty, sprec_real ] )
         # "struct s1_ty { int v1; float v2; };"
     
     # pointers
    -intptr_ty   = Type.pointer(int_ty)         # "typedef int *intptr_ty;"
    +intptr_ty   = Type.pointer(int_ty)         # "typedef int *intptr_ty;"
     
     # functions
    -f1 = Type.function( int_ty, [ int_ty ] )
    +f1 = Type.function( int_ty, [ int_ty ] )
         # functions that take 1 int_ty and return 1 int_ty
     
    -f2 = Type.function( Type.void(), [ int_ty ] )
    +f2 = Type.function( Type.void(), [ int_ty ] )
         # functions that take 1 int_ty and return nothing
     
    -fnargs = [ Type.pointer( Type.int(8) ) ]
    -printf = Type.function( Type.int(), fnargs, True )
    +fnargs = [ Type.pointer( Type.int(8) ) ]
    +printf = Type.function( Type.int(), fnargs, True )
         # variadic function
     

    Values (llvm.core)

    @@ -1671,19 +1674,20 @@ http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
    #!/usr/bin/env python
     
    -ti = Type.int()                         # a 32-bit int type
    +ti = Type.int()                         # a 32-bit int type
     
    -k1 = Constant.int(ti, 42)               # "int k1 = 42;"
    -k2 = k1.add( Constant.int( ti, 10 ) )   # "int k2 = k1 + 10;"
    +k1 = Constant.int(ti, 42)               # "int k1 = 42;"
    +k2 = k1.add( Constant.int( ti, 10 ) )   # "int k2 = k1 + 10;"
     
    -tr = Type.float()
    +tr = Type.float()
     
    -r1 = Constant.real(tr, "3.141592")      # create from a string
    -r2 = Constant.real(tr, 1.61803399)      # create from a Python float
    +r1 = Constant.real(tr, "3.141592")      # create from a string
    +r2 = Constant.real(tr, 1.61803399)      # create from a Python float
     

    The following constructors (static methods) can be used to create constants:

    +
    @@ -1809,6 +1813,7 @@ cellspacing="0" cellpadding="4">

    The following operations are available:

    +
    @@ -1955,7 +1960,31 @@ cellspacing="0" cellpadding="4"> + + + + + + + + + + + + - - - - - - - - - - - - @@ -2242,7 +2247,7 @@ cellspacing="0" cellpadding="4"> RPRED_FALSE @@ -2250,7 +2255,7 @@ cellspacing="0" cellpadding="4"> RPRED_OEQ @@ -2258,7 +2263,7 @@ cellspacing="0" cellpadding="4"> RPRED_OGT @@ -2266,7 +2271,7 @@ cellspacing="0" cellpadding="4"> RPRED_OGE @@ -2274,7 +2279,7 @@ cellspacing="0" cellpadding="4"> RPRED_OLT @@ -2282,7 +2287,7 @@ cellspacing="0" cellpadding="4"> RPRED_OLE @@ -2290,7 +2295,7 @@ cellspacing="0" cellpadding="4"> RPRED_ONE @@ -2298,7 +2303,7 @@ cellspacing="0" cellpadding="4"> RPRED_ORD @@ -2306,7 +2311,7 @@ cellspacing="0" cellpadding="4"> RPRED_UNO @@ -2314,7 +2319,7 @@ cellspacing="0" cellpadding="4"> RPRED_UEQ @@ -2322,7 +2327,7 @@ cellspacing="0" cellpadding="4"> RPRED_UGT @@ -2330,7 +2335,7 @@ cellspacing="0" cellpadding="4"> RPRED_UGE @@ -2338,7 +2343,7 @@ cellspacing="0" cellpadding="4"> RPRED_ULT @@ -2346,7 +2351,7 @@ cellspacing="0" cellpadding="4"> RPRED_ULE @@ -2354,7 +2359,7 @@ cellspacing="0" cellpadding="4"> RPRED_UNE @@ -2362,12 +2367,28 @@ cellspacing="0" cellpadding="4"> RPRED_TRUE
    - shl + k.shl(k2) + + Shift k left by k2 bits. +
    + k.lshr(k2) + + Shift k logically right by k2 bits (new bits are 0s). +
    + k.ashr(k2) + + Shift k arithmetically right by k2 bits (new bits are same as previous sign bit). +
    + k.gep(indices) TODO @@ -1963,50 +1992,26 @@ cellspacing="0" cellpadding="4">
    - lshr + k.trunc(ty) - TODO + Truncate k to a type ty of lower bitwidth.
    - ashr + k.sext(ty) - TODO + Sign extend k to a type ty of higher bitwidth, while extending the sign bit.
    - gep + k.zext(ty) - TODO -
    - trunc - - TODO -
    - sext - - TODO -
    - zext - - TODO + Sign extend k to a type ty of higher bitwidth, all new bits are 0s.
    - + Always false
    - + True if ordered and equal
    - + True if ordered and greater than
    - + True if ordered and greater than or equal
    - + True if ordered and less than
    - + True if ordered and less than or equal
    - + True if ordered and operands are unequal
    - + True if ordered (no NaNs)
    - + True if unordered: isnan(X) | isnan(Y)
    - + True if unordered or equal
    - + True if unordered or greater than
    - + True if unordered, greater than or equal
    - + True if unordered, or less than
    - + True if unordered, less than or equal
    - + True if unordered or not equal
    - + Always true
    +
    +
    llvm.core.Constant
    +
    +
    Base Class
      +
    • +

      +llvm.core.Value +

      +
    • +
    +
    Static Constructors
    +

    See table of constructors above for full list.

    +
    Methods
    +

    See table of operations above for full list. There are no other +methods.

    +

    TypeHandle (llvm.core)

    TODO

    Instructions (llvm.core)

    @@ -2385,9 +2406,134 @@ cellspacing="0" cellpadding="4">

    Pass Managers and Passes (llvm.passes)

    TODO

-

Annotated Examples

+

Annotated Examples

-

TODO

+

A Simple Function

+

Let's create a module containing a single function, corresponding to the +C function:

+
+
+
int sum(int a, int b)
+{
+    return a + b;
+}
+
+

Here's how it looks like:

+
+
+
#!/usr/bin/env python
+
+# Import the llvm-py modules.
+from llvm import *
+from llvm.core import *
+
+# Create a module.
+my_module = Module.new('my_module')
+
+# All the types involved here are "int"s. This type is represented
+# by an object of the llvm.core.Type class:
+ty_int = Type.int()   # by default 32 bits
+
+# We need to represent the class of functions that accept two integers
+# and return an integer. This is represented by an object of the
+# function type (llvm.core.FunctionType):
+ty_func = Type.function(ty_int, [ty_int, ty_int])
+
+# Now we need a function named 'sum' of this type. Functions are not
+# free-standing (in llvm-py); it needs to be contained in a module.
+f_sum = my_module.add_function(ty_func, "sum")
+
+# Let's name the function arguments as 'a' and 'b'.
+f_sum.args[0].name = "a"
+f_sum.args[1].name = "b"
+
+# Our function needs a "basic block" -- a set of instructions that
+# end with a terminator (like return, branch etc.). By convention
+# the first block is called "entry".
+bb = f_sum.append_basic_block("entry")
+
+# Let's add instructions into the block. For this, we need an
+# instruction builder:
+builder = Builder.new(bb)
+
+# OK, now for the instructions themselves. We'll create an add
+# instruction that returns the sum as a value, which we'll use
+# a ret instruction to return.
+tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
+builder.ret(tmp)
+
+# We've completed the definition now! Let's see the LLVM assembly
+# language representation of what we've created:
+print my_module
+
+

Here is the output:

+
+
+
; ModuleID = 'my_module'
+
+define i32 @sum(i32 %a, i32 %b) {
+entry:
+        %tmp = add i32 %a, %b           ; <i32> [#uses=1]
+        ret i32 %tmp
+}
+
+

Adding JIT Compilation

+

Let's compile this function in-memory and run it.

+
+
+
#!/usr/bin/env python
+
+# Import the llvm-py modules.
+from llvm import *
+from llvm.core import *
+from llvm.ee import *          # new import: ee = Execution Engine
+
+# Create a module, as in the previous example.
+my_module = Module.new('my_module')
+ty_int = Type.int()   # by default 32 bits
+ty_func = Type.function(ty_int, [ty_int, ty_int])
+f_sum = my_module.add_function(ty_func, "sum")
+f_sum.args[0].name = "a"
+f_sum.args[1].name = "b"
+bb = f_sum.append_basic_block("entry")
+builder = Builder.new(bb)
+tmp = builder.add(f_sum.args[0], f_sum.args[1], "tmp")
+builder.ret(tmp)
+
+# Create a module provider object first. Modules can come from
+# in-memory IRs like what we created now, or from bitcode (.bc)
+# files. The module provider abstracts this detail.
+mp = ModuleProvider.new(my_module)
+
+# Create an execution engine object. This will create a JIT compiler
+# on platforms that support it, or an interpreter otherwise.
+ee = ExecutionEngine.new(mp)
+
+# The arguments needs to be passed as "GenericValue" objects.
+arg1 = GenericValue.int(ty_int, 100)
+arg2 = GenericValue.int(ty_int, 42)
+
+# Now let's compile and run!
+retval = ee.run_function(f_sum, [arg1, arg2])
+
+# The return value is also GenericValue. Let's print it.
+print "returned", retval.as_int()
+
+

And here's the output:

+
+
+
returned 142
+
+

That was easy, right?!

About the llvm-py Project

@@ -2413,7 +2559,7 @@ reached at mdevan.foobar@gmail.com.