~/llvm-2.3$ ./configure --enable-pic --enable-optimized+
~/llvm-2.4$ ./configure --enable-pic --enable-optimized
From 3bbc5685a8fd48d37721762fa509b6fd43e6704f Mon Sep 17 00:00:00 2001
From: "mdevan.foobar"
llvm-py is just hatching. It should be stable enough to start hacking away, though. Be sure to send in a patch if you miss any specific LLVM API.
Availability: llvm-py is available (as a source package) for LLVM 2.3 -and Python 2.5. It has been built and tested on Linux (x86, amd64) and -is reported to work with OpenBSD. It is expected to be usable on -various unices, as well as with Python 2.4.
LLVM 2.4: Read this if you're using LLVM -2.4!
Availability: llvm-py is available (as a source package) for LLVM 2.4 +and Python 2.5. It has been built and tested on Linux and FreeBSD +(x86 and amd64).
+ 0.5 released. For LLVM 2.4. +
+llvm-py provides Python bindings for LLVM. This document explains how +
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.
+of LLVM is assumed.LLVM (Low-Level Virtual Machine) provides enough +
LLVM (Low-Level Virtual Machine) provides enough infrastructure to use it as the backend for your compiled, or JIT-compiled language. It provides extensive optimization support, and static and dynamic (JIT) backends for many platforms. See the website at -http://www.llvm.org/ to discover more.
-Python bindings for LLVM provides a gentler learning curve for working +http://www.llvm.org/ to discover more.
Python bindings for LLVM provides a gentler learning curve for working with the LLVM APIs. It should also be easier to create working -prototypes and experimental languages using this medium.
-Both LLVM and llvm-py are distributed under (different) permissive +prototypes and experimental languages using this medium.
Both LLVM and llvm-py are distributed under (different) permissive open source licenses. llvm-py uses the new BSD license. More -information is available here.
-Currently, llvm-py has been built and tested only on Linux (i386, amd64) +information is available here.
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.
-llvm-py requires verion 2.3 of LLVM. It will not work with previous -versions. If you're using LLVM 2.4, see below.
-llvm-py has been built and tested with Python 2.5. It should work with -Python 2.4, with minimal changes, if any.
+other unices. Windows is not supported, for a variety of reasons.llvm-py 0.5 requires verion 2.4 of LLVM. It will not work with previous +versions.
llvm-py has been built and tested with Python 2.5. It should work with +Python 2.4, with minimal changes, if any.
llvm-py is distributed as a source tarball. You'll need to build and +
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:
-C and C++ compilers (gcc/g++) @@ -99,116 +96,80 @@ Python development files (headers and libraries) LLVM, either installed or built
On debian-based systems, the first three can be installed with the +
On debian-based systems, the first three can be installed with the command sudo apt-get install gcc g++ python python-dev. Note that ubuntu repository has an old version of llvm (1.8) which will not work -with llvm-py.
-It does not matter which compiler LLVM itself was built with (g++, +with llvm-py.
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.
-Tip: If LLVM 2.3 does not install cleanly, try installing “ocamldoc” -first.
-The result of an LLVM build is a set of static libraries and object +been tried only with gcc/g++ though.
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 -fPIC option (generate position independent code). Be sure to use the —enable-pic option while -configuring LLVM (default is no PIC), like this:
+configuring LLVM (default is no PIC), like this:~/llvm-2.3$ ./configure --enable-pic --enable-optimized+
~/llvm-2.4$ ./configure --enable-pic --enable-optimized
Inorder to build llvm-py, it's build script needs to know from where it +
Inorder to build llvm-py, it's build script needs to know from where it can invoke the llvm helper program, llvm-config. If you've installed LLVM, then this will be available in your PATH, and nothing further needs to be done. If you've built LLVM yourself, or for any reason llvm-config is not in your PATH, you'll need to pass the full path -of llvm-config to the build script.
-You'll need to be root to install llvm-py. Remember that your PATH +of llvm-config to the build script.
You'll need to be root to install llvm-py. Remember that your PATH is different from that of root, so even if llvm-config is in your -PATH, it may not be available when you do sudo.
-The commands illustrated below assume that the LLVM source is available +PATH, it may not be available when you do sudo.
The commands illustrated below assume that the LLVM source is available under /home/mdevan/llvm. If you've a previous version of llvm-py installed, it is recommended to remove it first, as described -below.
-If you have llvm-config in your path, you can build and install -llvm-py this way:
+below.If you have llvm-config in your path, you can build and install +llvm-py this way:
$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ sudo python setup.py install
If you need to tell the build script where llvm-config is, do it this -way:
+If you need to tell the build script where llvm-config is, do it this +way:
$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Release/bin/llvm-config
To build a debug version of llvm-py, that links against the debug -libraries of LLVM, use this:
+To build a debug version of llvm-py, that links against the debug +libraries of LLVM, use this:
$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ 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
Be warned that debug binaries will be huge (100MB+) ! They are required -only if you need to debug into LLVM also.
-setup.py is a standard Python distutils script. See the Python +
Be warned that debug binaries will be huge (100MB+) ! They are required +only if you need to debug into LLVM also.
setup.py is a standard Python distutils script. See the Python documentation regarding Installing Python Modules and Distributing -Python Modules for more information on such scripts.
-LLVM 2.4 is currently in progress. There are incompatible API changes -from LLVM 2.3. The latest release of llvm-py will not compile against -it.
-The llvm-py SVN has a branch called -llvm2.4, -which attempts to track the changes happening in LLVM 2.4. There are -however, some caveats:
--There are no releases from this branch. -
--When LLVM 2.4 is released, then these changes will be merged to main. - From then on llvm-py will support LLVM 2.4 and no longer LLVM 2.3. -
--This branch is not religiously kept up-to-date with the changes - happening in LLVM SVN. Therefore, it may not work for you, but might - still be worth a try. -
-llvm-py can be checked out from this branch like this:
-$ svn co http://llvm-py.googlecode.com/svn/branches/llvm2.4 llvm-py-2.4-
The rest of the steps (build, install) remain the same as before.
-To get rid of llvm-py completely, if you wish to do so:
+Python Modules for more information on such scripts.To get rid of llvm-py completely, if you wish to do so:
# rm -rf /usr/lib/python2.5/site-packages/llvm # rm -f /usr/lib/python2.5/site-packages/llvm_py-0.1.egg-info
You need to be root to do this. @@ -225,19 +186,19 @@ Note that there are version numbers (both Python's and llvm-py's) which you might need to change to suit your system.
This section explains a few concepts related to LLVM.
-The intermediate representation, or IR for short, is an in-memory data +
This section explains a few concepts related to LLVM.
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 sum that takes two integers and returns their sum, we need to -follow these steps:
-create an integer type ti of required bitwidth @@ -264,7 +225,7 @@ add a basic block to the function using a helper object called an instruction builder, add two instructions into the basic block:
-an instruction to add the two arguments and store the result into @@ -276,25 +237,25 @@ an instruction to add the two arguments and store the result into a return instruction to return the value of the temporary variable
(A basic block is a block of instructions.)
-LLVM has it's own instruction set; the instructions used above (add +
(A basic block is a block of instructions.)
LLVM has it's own instruction set; the instructions used above (add and ret) 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.
-All LLVM instructions are represented in the Static Single Assignment +represented cleanly in the IR.
All LLVM instructions are represented in the Static Single Assignment (SSA) form. Essentially, this means that any variable can be assigned to only once. Such a representation facilitates better optimization, among -other benefits.
-A consequence of single assignment are PHI (Φ) nodes. These +other benefits.
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 b at the end of -execution of the snippet below:
+execution of the snippet below:a = 1; @@ -302,10 +263,10 @@ if (v < 10) a = 2; b = a;
cannot be determined statically. The value of 2 cannot be assigned to +
cannot be determined statically. The value of 2 cannot be assigned to the original a, since a can be assigned to only once. There are two a 's in there, and the last assignment has to choose between which -version to pick. This is accomplished by adding a PHI node:
+version to pick. This is accomplished by adding a PHI node:a1 = 1; @@ -313,26 +274,26 @@ if (v < 10) a2 = 2; b = PHI(a1, a2);
The PHI node selects a1 or a2, depending on where the control +
The PHI node selects a1 or a2, depending on where the control reached the PHI node. The argument a1 of the PHI node is associated -with the block "a1 = 1;" and a2 with the block "a2 = 2;".
-PHI nodes have to be explicitly created in the LLVM IR. Accordingly the -LLVM instruction set has an instruction called phi.
-The LLVM IR can be represented offline in two formats +with the block "a1 = 1;" and a2 with the block "a2 = 2;".
PHI nodes have to be explicitly created in the LLVM IR. Accordingly the +LLVM instruction set has an instruction called phi.
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 same information. Each format can be -converted into the other two formats (using LLVM APIs).
-The LLVM demo page lets you type in C or C++ +converted into the other two formats (using LLVM APIs).
The LLVM demo page lets you type in C or C++ code, converts it into LLVM IR and outputs the IR as LLVM assembly -language code.
-Just to get a feel of the LLVM assembly language, here's a function in C, -and the corresponding LLVM assembly (as generated by the demo page):
+language code.Just to get a feel of the LLVM assembly language, here's a function in C, +and the corresponding LLVM assembly (as generated by the demo page):
The corresponding LLVM assembly:
+The corresponding LLVM assembly:
; ModuleID = '/tmp/webcompile/_4940_0.bc'
@@ -373,14 +334,14 @@ bb10: ; preds = %entry
ret i32 0
}
Note the usage of SSA form and the total absence of any loop or +
Note the usage of SSA form and the total absence of any loop or recursion at all! The long string called target datalayout is a specification of the platform ABI (like endianness, sizes of types, -alignment etc.).
-The LLVM Language Reference +alignment etc.).
The LLVM Language Reference 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.
+to it's documentation.Modules, in the LLVM IR, are similar to a single C language source -file (.c file). A module contains:
-Modules, in the LLVM IR, are similar to a single C language source +file (.c file). A module contains:
functions (declarations and definitions) @@ -557,39 +518,39 @@ global variables and constants global type aliases (typedef-s)
Modules are top-level containers; all executable code representation is -contained within modules.
-LLVM provides quite a few optimization algorithms that work on the IR. +
Modules are top-level containers; all executable code representation is +contained within modules.
LLVM provides quite a few optimization algorithms that work on the IR. These algorithms are organized as passes. 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.
-This LLVM documentation page -describes all the available passes, and what they do.
-LLVM does not automatically choose to run any passes, anytime. Passes +used by passes that do optimizations) or even printing call graphs.
This LLVM documentation page +describes all the available passes, and what they do.
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.
-There is an LLVM binary called opt, +most suitable for the code in the module.
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 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.)
+any stage, and perform any transforms on it as you like.)The llvm-py is a Python package, consisting of 6 modules, that wrap +
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.
-Out of the 6 modules, one is an “extension” module (i.e., it is +probably know why this is a good idea.
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:
-llvm — top-level package, common classes (like exceptions) @@ -610,24 +571,24 @@ leaves 4 public modules. These are:
llvm.passes — pass manager and passes related APIsThe modules contain only classes and (integer) constants. Mostly simple +
The modules contain only classes and (integer) constants. Mostly simple Python constructs are used (deliberately) — property() and property decorators 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.
-Here is a quick overview of the contents of each package:
-Here is a quick overview of the contents of each package:
LLVMException — exception class (currently the only one)
Module — represents an LLVM Module @@ -712,8 +673,8 @@ constants VISIBILITY_* that represents visibility of symbols constants ATTR_* that represent function parameter attributes
ExecutionEngine — represents an execution engine (which can be an @@ -726,8 +687,8 @@ TargetData — represents the ABI of the target platform (details like sizes and alignment of primitive types, endinanness etc)
PassManager — represents an LLVM pass manager @@ -743,13 +704,12 @@ FunctionPassManager — represents an LLVM function pass manager constants PASS_* that represent various passes
Pythonically, modules are imported with the statement "import +
Pythonically, modules are imported with the statement "import llvm.core". However, you might find it more convenient to import -llvm-py modules thus:
+llvm-py modules thus:This avoids quite some typing. Both conventions work, however.
+This avoids quite some typing. Both conventions work, however.
| @@ -770,12 +730,12 @@ interpreter or the object? of to get online help. (Note: not complete yet!) |
Modules are top-level container objects. You need to create a module +
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 Module.new:
+Modules are created using the static method Module.new: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.
+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.
| @@ -796,55 +756,55 @@ a Module object. This is a common feature for all llvm-py classes. |
Convention
-All llvm-py objects are instantiated using static methods of -corresponding classes. Constructors should not be used. +All llvm-py objects are instantiated using static methods of +corresponding classes. Constructors should not be used. |
The argument my_module is a module identifier (a plain string). A +
The argument my_module is a module identifier (a plain string). A module can also be constructed via deserialization from a bit code file, using the static method from_bitcode. This method takes a file-like object as argument, i.e., it should have a read() method that returns the entire data in a single call, as is the case with the builtin file -object. Here is an example:
+object. Here is an example:# create a module from a bit code file bcfile = file("test.bc") -my_module = Module.from_bitcode(bcfile) +my_module = Module.from_bitcode(bcfile)
There is corresponding serialization method also, called to_bitcode:
+There is corresponding serialization method also, called to_bitcode:
# write out a bit code file from the module bcfile = file("test.bc", "w") -my_module.to_bitcode(bcfile) +my_module.to_bitcode(bcfile)
Modules can also be constructed from LLVM assembly files (.ll files). +
Modules can also be constructed from LLVM assembly files (.ll files). The static method from_assembly can be used for this. Similar to the from_bitcode method, this one also takes a file-like object as -argument:
+argument:# create a module from an assembly file llfile = file("test.ll") -my_module = Module.from_assembly(llfile) +my_module = Module.from_assembly(llfile)
Modules can be converted into their assembly representation by -stringifying them (see below).
+Modules can be converted into their assembly representation by +stringifying them (see below).
|
Convention
-All llvm-py objects (where it makes sense), when stringified, return + All llvm-py objects (where it makes sense), when stringified, return the LLVM assembly representation. “ print module_obj ” for example, -prints the LLVM assembly form of the entire module. -Such objects, when compared for equality, internally compare these -string representations. +prints the LLVM assembly form of the entire module.Such objects, when compared for equality, internally compare these +string representations. |
Types are what you think they are. A instance of llvm.core.Type, or +
Types are what you think they are. A instance of llvm.core.Type, 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 llvm.core.Type itself and the rest are represented using derived classes of llvm.core.Type. As usual, an instance is created via one of the static methods of Type. These methods return an instance of either llvm.core.Type itself or one of its derived -classes.
-The following table lists all the available types along with the static +classes.
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.
+object is actually returned by the static method.The class hierarchy is:
+The class hierarchy is:
Type @@ -1231,11 +1191,11 @@ cellspacing="0" cellpadding="4"> PointerType VectorType
The class-level documentation follows:
+The class-level documentation follows:
TYPE_VOID = 0 -TYPE_FLOAT = 1 -TYPE_DOUBLE = 2 -TYPE_X86_FP80 = 3 -TYPE_FP128 = 4 -TYPE_PPC_FP128 = 5 -TYPE_LABEL = 6 -TYPE_INTEGER = 7 -TYPE_FUNCTION = 8 -TYPE_STRUCT = 9 -TYPE_ARRAY = 10 -TYPE_POINTER = 11 -TYPE_OPAQUE = 12 -TYPE_VECTOR = 13 +TYPE_VOID = 0 +TYPE_FLOAT = 1 +TYPE_DOUBLE = 2 +TYPE_X86_FP80 = 3 +TYPE_FP128 = 4 +TYPE_PPC_FP128 = 5 +TYPE_LABEL = 6 +TYPE_INTEGER = 7 +TYPE_FUNCTION = 8 +TYPE_STRUCT = 9 +TYPE_ARRAY = 10 +TYPE_POINTER = 11 +TYPE_OPAQUE = 12 +TYPE_VECTOR = 13
Example:
+Example:
assert Type.int().kind == TYPE_INTEGER -assert Type.void().kind == TYPE_VOID +assert Type.int().kind == TYPE_INTEGER +assert Type.void().kind == TYPE_VOID
llvm.core.Type
llvm.core.Type
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) +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)
llvm.core.Type
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) +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)
llvm.core.Type
llvm.core.Type
llvm.core.Type
Here is an example that demonstrates the creation of types:
+Here is an example that demonstrates the creation of types:
#!/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, int_ty ] ) +f2 = Type.function( Type.void(), [ int_ty, int_ty ] ) # functions that take 2 int_tys and return nothing -f3 = Type.function( Type.void(), ( int_ty, int_ty ) ) +f3 = Type.function( Type.void(), ( int_ty, int_ty ) ) # same as f2; any iterable can be used -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
TypeHandle objects are used to create recursive types, like this linked -list node structure in C:
+TypeHandle objects are used to create recursive types, like this linked +list node structure in C:
struct node +struct node { int data; - struct node *next; + struct node *next; };
This can be realized in llvm-py like this:
+This can be realized in llvm-py like this:
#!/usr/bin/env python
@@ -1726,24 +1686,24 @@ m.add_type_name("struct.node", th.type)
# show what we created
print m
which gives the output:
+which gives the output:
; ModuleID = 'mod1'
%struct.node = type { i32, %struct.node* }
For more details on what is going on here, please refer the LLVM +
For more details on what is going on here, please refer the LLVM Programmer's Manual section "LLVM Type Resolution". The TypeHandle class of llvm-py corresponds to llvm::PATypeHolder in C++. The above example is available as test/typehandle.py -in the source distribution.
+in the source distribution.llvm.core.Value is the base class of all values computed by a program +
llvm.core.Value 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 llvm.core.Type).
-The class hierarchy is:
+associated with it (an object of llvm.core.Type).The class hierarchy is:
Value
@@ -1786,7 +1746,7 @@ associated with it (an object of llvm.core.Type).
SwitchInstruction
BasicBlock
The Value class is abstract, it's not meant to be instantiated. +
The Value class is abstract, it's not meant to be instantiated. Constant-s represent constants that appear within code or as initializers of globals. They are constructed using static methods of Constant. The Constant class is covered in a separate section below. @@ -1795,12 +1755,12 @@ objects contain Argument objects, which represent the actual, local-variable-like arguments of the function (not to be confused with the arguments returned by a function type object — these represent the type of the arguments). The various Instruction-s are created by -the Builder class. These are also covered separately.
-Value objects have a type (read-only), and a name (read-write).
+the Builder class. These are also covered separately.Value objects have a type (read-only), and a name (read-write).
Constant-s represents constants that appear within the code. The +
Constant-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 Constant object, an operation (like addition, subtraction etc) can be specified, to yield a new Constant object. Let's see some -examples:
+examples:#!/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:
-The following constructors (static methods) can be used to create +constants:
The following operations on constants are supported. For more details on +
The following operations on constants are supported. For more details on any operation, consult the Constant Expressions -section of the LLVM Language Reference.
- +Predicates for use with icmp instruction are listed below. All -of these are integer constants defined in the llvm.core module.
+Predicates for use with icmp instruction are listed below. All +of these are integer constants defined in the llvm.core module.
Predicates for use with fcmp instruction are listed below. All -of these are integer constants defined in the llvm.core module.
+Predicates for use with fcmp instruction are listed below. All +of these are integer constants defined in the llvm.core module.
The section property can be assigned strings (like ".rodata"), which +
The section property can be assigned strings (like ".rodata"), which will be used if the target supports it. Visibility property can be set to one of thse constants (from llvm.core, see also -LLVM docs):
+LLVM docs):The alignment property can be 0 (default), or can be set to a power of +
The alignment property can be 0 (default), or can be set to a power of 2. The read-only property is_declaration can be used to check if the global is a declaration or not. The module to which the global belongs -to can be retrieved using the module property (read-only).
+to can be retrieved using the module property (read-only).llvm.core.Constant
Global variables (llvm.core.GlobalVariable) are subclasses of +
Global variables (llvm.core.GlobalVariable) are subclasses of llvm.core.GlobalValue and represent module-level variables. These can have optional initializers and can be marked as constants. Global variables can be created either by using the add_global_variable method of the Module class (see above), or by using the static method -GlobalVariable.new.
+GlobalVariable.new.# create a global variable using add_global_variable method -gv1 = module_obj.add_global_variable(Type.int(), "gv1") +gv1 = module_obj.add_global_variable(Type.int(), "gv1") # or equivalently, using a static constructor method -gv2 = GlobalVariable.new(module_obj, Type.int(), "gv2") +gv2 = GlobalVariable.new(module_obj, Type.int(), "gv2")
Existing global variables of a module can be accessed by name using +
Existing global variables of a module can be accessed by name using module_obj.get_global_variable_named(name) or GlobalVariable.get. All existing global variables can be enumerated via iterating over the -property module_obj.global_variables.
+property module_obj.global_variables.# retrieve a reference to the global variable gv1, # using the get_global_variable_named method -gv1 = module_obj.get_global_variable_named("gv1") +gv1 = module_obj.get_global_variable_named("gv1") # or equivalently, using the static `get` method: -gv2 = GlobalVariable.get(module_obj, "gv2") +gv2 = GlobalVariable.get(module_obj, "gv2") # list all global variables in a module -for gv in module_obj.global_variables: +for gv in module_obj.global_variables: print gv.name, "of type", gv.type
The initializer for a global variable can be set by assigning to the +
The initializer for a global variable can be set by assigning to the initializer property of the object. The is_global_constant property -can be used to indicate that the variable is a global constant.
-Global variables can be delete using the delete method. Do not use the -object after calling delete on it.
+can be used to indicate that the variable is a global constant.Global variables can be delete using the delete method. Do not use the +object after calling delete on it.
# add an initializer 10 (32-bit integer) -gv.initializer = Constant.int( Type.int(), 10 ) +gv.initializer = Constant.int( Type.int(), 10 ) # delete the global gv.delete() # DO NOT dereference `gv' beyond this point! -gv = None +gv = None
llvm.core.GlobalValue
Functions are represented by llvm.core.Function objects. They are +
Functions are represented by llvm.core.Function objects. They are contained within modules, and can be created either with the method module_obj.add_function or the static constructor Function.new. References to functions already present in a module can be retrieved via module.get_function_named or by the static constructor method Function.get. All functions in a module can be enumerated by iterating -over module_obj.functions.
+over module_obj.functions.# create a type, representing functions that take an integer and return # a floating point value. -ft = Type.function( Type.float(), [ Type.int() ] ) +ft = Type.function( Type.float(), [ Type.int() ] ) # create a function of this type -f1 = module_obj.add_function(ft, "func1") +f1 = module_obj.add_function(ft, "func1") # or equivalently, like this: -f2 = Function.new(module_obj, ft, "func2") +f2 = Function.new(module_obj, ft, "func2") # get a reference to an existing function -f3 = module_obj.get_function_named("func3") +f3 = module_obj.get_function_named("func3") # or like this: -f4 = Function.get(module_obj, "func4") +f4 = Function.get(module_obj, "func4") # list all function names in a module -for f in module_obj.functions: +for f in module_obj.functions: print f.name
References to intrinsic functions can be got via the static constructor +
References to intrinsic functions can be got via the static constructor intrinsic. This returns a Function object, calling which is equivalent to invoking the intrinsic. The intrinsic method has to be called with a module object, an instrinic ID (which is a numeric constant) and a list of the types of arguments (which LLVM uses to -resolve overloaded intrinsic functions).
+resolve overloaded intrinsic functions).# get a reference to the llvm.bswap intrinsic -bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()]) +bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()]) # call it builder.call(bswap, [value])
Here, the constant INTR_BSWAP, available from llvm.core, represents +
Here, the constant INTR_BSWAP, available from llvm.core, represents the LLVM intrinsic llvm.bswap. The [Type.int()] selects the version of llvm.bswap that has a single 32-bit integer argument. The list of intrinsic IDs defined as integer constants -in llvm.core. These are:
+in llvm.core. These are:| - INTR_DBG_STOPPOINT + INTR_ATOMIC_CMP_SWAP | - INTR_MEMSET_I64 - | - -||
| - INTR_ARM_THREAD_POINTER - | -- INTR_EH_DWARF_CFA - | -- INTR_PART_SELECT - | -|
| - INTR_ATOMIC_LAS - | -- INTR_EH_EXCEPTION - | -- INTR_PART_SET - | -|
| - INTR_ATOMIC_LCS - | -- INTR_EH_RETURN - | -- INTR_PCMARKER + INTR_ATOMIC_LOAD_ADD | |
| INTR_ATOMIC_LOAD_AND | -- INTR_EH_SELECTOR_I32 - | -- INTR_POW - | -|
| INTR_ATOMIC_LOAD_MAX | -- INTR_EH_SELECTOR_I64 - | -- INTR_POWI - | -|
| INTR_ATOMIC_LOAD_MIN | -- INTR_EH_TYPEID_FOR_I32 - | -- INTR_PREFETCH - | |
| + INTR_ATOMIC_LOAD_NAND + | INTR_ATOMIC_LOAD_OR | - INTR_EH_TYPEID_FOR_I64 - | -- INTR_READCYCLECOUNTER + INTR_ATOMIC_LOAD_SUB |
| INTR_ATOMIC_LOAD_UMAX | -- INTR_EH_UNWIND_INIT - | -- INTR_RETURNADDRESS - | -|
| INTR_ATOMIC_LOAD_UMIN | -- INTR_FLT_ROUNDS - | -- INTR_SETJMP - | -|
| INTR_ATOMIC_LOAD_XOR | -- INTR_FRAMEADDRESS - | -- INTR_SIGLONGJMP - | -|
| - INTR_ATOMIC_LSS - | -- INTR_GCREAD - | -- INTR_SIGSETJMP - | |
| INTR_ATOMIC_SWAP | -- INTR_GCROOT - | -- INTR_SIN - | -|
| INTR_BSWAP | -- INTR_GCWRITE - | -- INTR_SQRT - | -|
| INTR_COS | -- INTR_INIT_TRAMPOLINE - | -- INTR_STACKRESTORE - | |
| INTR_CTLZ | -- INTR_LONGJMP - | -- INTR_STACKSAVE - | -|
| INTR_CTPOP | -- INTR_MEMCPY_I32 - | -- INTR_TRAP - | -|
| INTR_CTTZ | -- INTR_MEMCPY_I64 - | -- INTR_VACOPY - | |
| INTR_DBG_DECLARE | -- INTR_MEMMOVE_I32 - | -- INTR_VAEND - | -|
| INTR_DBG_FUNC_START | -- INTR_MEMMOVE_I64 - | -- INTR_VAR_ANNOTATION - | -|
| INTR_DBG_REGION_END | -- INTR_MEMORY_BARRIER - | -- INTR_VASTART - | |
| INTR_DBG_REGION_START | + INTR_DBG_STOPPOINT + | ++ INTR_EH_DWARF_CFA + | +|
| + INTR_EH_EXCEPTION + | ++ INTR_EH_RETURN_I32 + | ++ INTR_EH_RETURN_I64 + | +|
| + INTR_EH_SELECTOR_I32 + | ++ INTR_EH_SELECTOR_I64 + | ++ INTR_EH_TYPEID_FOR_I32 + | +|
| + INTR_EH_TYPEID_FOR_I64 + | ++ INTR_EH_UNWIND_INIT + | ++ INTR_EXP + | +|
| + INTR_EXP2 + | ++ INTR_FLT_ROUNDS + | ++ INTR_FRAMEADDRESS + | +|
| + INTR_GCREAD + | ++ INTR_GCROOT + | ++ INTR_GCWRITE + | +|
| + INTR_INIT_TRAMPOLINE + | ++ INTR_LOG + | ++ INTR_LOG10 + | +|
| + INTR_LOG2 + | ++ INTR_LONGJMP + | ++ INTR_MEMCPY_I32 + | +|
| + INTR_MEMCPY_I64 + | ++ INTR_MEMMOVE_I32 + | ++ INTR_MEMMOVE_I64 + | +|
| + INTR_MEMORY_BARRIER + | +INTR_MEMSET_I32 | - + INTR_MEMSET_I64 + | +|
| + INTR_PART_SELECT + | ++ INTR_PART_SET + | ++ INTR_PCMARKER + | +|
| + INTR_POW + | ++ INTR_POWI + | ++ INTR_PREFETCH + | +|
| + INTR_READCYCLECOUNTER + | ++ INTR_RETURNADDRESS + | ++ INTR_SETJMP + | +|
| + INTR_SIGLONGJMP + | ++ INTR_SIGSETJMP + | ++ INTR_SIN + | +|
| + INTR_SQRT + | ++ INTR_STACKRESTORE + | ++ INTR_STACKSAVE + | +|
| + INTR_TRAP + | ++ INTR_VACOPY + | ++ INTR_VAEND + | +|
| + INTR_VAR_ANNOTATION + | ++ INTR_VASTART + | +
There are also target-specific intrinsics (which correspond to that +
There are also target-specific intrinsics (which correspond to that target's CPU instructions) available, but are omitted here for brevity. Full list can be seen from core.py. @@ -3225,10 +3202,10 @@ for more information on the intrinsics, and the test directory in the source distribution for more examples. The intrinsic ID can be retrieved from a function object with the read-only property -intrinsic_id.
-The function's calling convention can be set using the +intrinsic_id.
The function's calling convention can be set using the calling_convention property. The following (integer) constants defined -in llvm.core can be used as values:
+in llvm.core can be used as values:See the LLVM docs for +
See the LLVM docs for more information on each. Backend-specific numbered conventions can be -directly set as numbers.
-An arbitrary string identifying which garbage collector to use can be -set or got with the property collector.
-The value objects corresponding to the arguments of a function can be +directly set as numbers.
An arbitrary string identifying which garbage collector to use can be +set or got with the property collector.
The value objects corresponding to the arguments of a function can be got using the read-only property args. These can be iterated over, and -also be indexed via integers. An example:
+also be indexed via integers. An example:Basic blocks (see later) are contained within functions. When newly +
Basic blocks (see later) are contained within functions. When newly created, a function has no basic blocks. They have to be added explicitly, using the append_basic_block method, which adds a new, empty basic block as the last one in the function. The first basic block @@ -3318,9 +3295,9 @@ method. The existing basic blocks can be enumerated by iterating over using the read-only property basic_blocks. The number of basic blocks can be got via basic_block_count method. Note that get_entry_basic_block is slightly faster than basic_blocks[0] and so -is basic_block_count, over len(f.basic_blocks).
+is basic_block_count, over len(f.basic_blocks).Functions can be deleted using the method delete. This deletes them +
Functions can be deleted using the method delete. This deletes them from their containing module. All references to the function object -should be dropped after delete has been called.
-Functions can be verified with the verify method. This does not work -properly yet (aborts on errors), investigation pending.
-The args property of llvm.core.Function objects yields +should be dropped after delete has been called.
Functions can be verified with the verify method. This does not work +properly yet (aborts on errors), investigation pending.
The args property of llvm.core.Function objects yields llvm.core.Argument objects. This allows for setting attributes for functions arguments. Argument objects cannot be constructed from user -code, the only way to get a reference to these are via functions.
-The method add_attribute and remove_attribute can be used to add or -remove the following attributes:
+code, the only way to get a reference to these are via functions.The method add_attribute and remove_attribute can be used to add or +remove the following attributes:
The corresponding +
The corresponding LLVM docs -provide more information.
-The alignment of any parameter can also be set via set_argument(a) -where a is a power of 2.
-TODO
-TODO
-TODO
-TODO
-TODO
-TODO. For now, see test/example-jit.py.
-TODO. For now, see test/passes.py.
+provide more information.The alignment of any parameter can also be set via set_argument(a) +where a is a power of 2.
TODO
TODO
TODO
TODO
TODO
TODO. For now, see test/example-jit.py.
TODO. For now, see test/passes.py.
llvm-py lives at +
llvm-py lives at http://mdevan.nfshost.com/llvm-py/. The code (subversion repository) and the issue tracker are hosted on the Google code hosting service, at @@ -3489,21 +3466,21 @@ Google code hosting service, at It is distributed under the new BSD license, the full license text is in the file named LICENSE -available in the source distribution.
-The entire llvm-py website is generated from marked up text files +available in the source distribution.
The entire llvm-py website is generated from marked up text files using the tool AsciiDoc. These text files and the (pre-)generated HTML pages are available in the source -distribution.
-llvm-py is an ongoing, live project. Your contributions in any form +distribution.
llvm-py is an ongoing, live project. Your contributions in any form are most welcome. You can checkout the latest SVN HEAD from -here.
-Mahadevan R wrote llvm-py and works on it in his spare time. He can be -reached at mdevan.foobar@gmail.com.
+here.Mahadevan R wrote llvm-py and works on it in his spare time. He can be +reached at mdevan.foobar@gmail.com.