Updated documentation and added more examples.
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@34 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
parent
18177ba0fa
commit
8e9d163e2b
5 changed files with 1681 additions and 365 deletions
38
test/example-jit.py
Normal file
38
test/example-jit.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/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()
|
||||||
|
|
||||||
|
|
@ -1,42 +1,45 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Import the llvm-py modules.
|
||||||
|
from llvm import *
|
||||||
from llvm.core import *
|
from llvm.core import *
|
||||||
|
|
||||||
## create a module
|
# Create an (empty) module.
|
||||||
module = Module.new("my_module")
|
my_module = Module.new('my_module')
|
||||||
|
|
||||||
## create a function type taking two doubles and returning a (32-bit) integer
|
# All the types involved here are "int"s. This type is represented
|
||||||
ty_double = Type.double()
|
# by an object of the llvm.core.Type class:
|
||||||
ty_int = Type.int()
|
ty_int = Type.int() # by default 32 bits
|
||||||
ty_func = Type.function( ty_int, [ ty_double, ty_double ] )
|
|
||||||
|
|
||||||
## create a function of this type
|
# We need to represent the class of functions that accept two integers
|
||||||
func = Function.new( module, ty_func, "foobar" )
|
# 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
|
# Now we need a function named 'sum' of this type. Functions are not
|
||||||
func.args[0].name = "arg1"
|
# free-standing (in llvm-py); it needs to be contained in a module.
|
||||||
func.args[1].name = "arg2"
|
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
|
# Our function needs a "basic block" -- a set of instructions that
|
||||||
entry = func.append_basic_block("entry")
|
# 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
|
# Let's add instructions into the block. For this, we need an
|
||||||
builder = Builder.new(entry)
|
# instruction builder:
|
||||||
|
builder = Builder.new(bb)
|
||||||
|
|
||||||
# add two args into tmp1
|
# OK, now for the instructions themselves. We'll create an add
|
||||||
tmp1 = builder.add(func.args[0], func.args[1], "tmp1")
|
# 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
|
# We've completed the definition now! Let's see the LLVM assembly
|
||||||
one = Constant.real( ty_double, 1.0 )
|
# language representation of what we've created:
|
||||||
tmp2 = builder.sub(tmp1, one, "tmp2")
|
print my_module
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
|
||||||
79
test/intrinsic.py
Normal file
79
test/intrinsic.py
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# This example shows how to use LLVM intrinsics.
|
||||||
|
|
||||||
|
from llvm.core import *
|
||||||
|
from llvm.ee import *
|
||||||
|
|
||||||
|
# setup a function and a builder
|
||||||
|
mod = Module.new('test')
|
||||||
|
functy = Type.function(Type.void(), [])
|
||||||
|
func = mod.add_function(functy, "showme")
|
||||||
|
block = func.append_basic_block("entry")
|
||||||
|
b = Builder.new(block)
|
||||||
|
|
||||||
|
# let's do bswap on a 32-bit integer using llvm.bswap
|
||||||
|
val = Constant.int(Type.int(), 42)
|
||||||
|
bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()])
|
||||||
|
b.call(bswap, [val])
|
||||||
|
print mod
|
||||||
|
|
||||||
|
# the output is:
|
||||||
|
#
|
||||||
|
# ; ModuleID = 'test'
|
||||||
|
#
|
||||||
|
# define void @showme() {
|
||||||
|
# entry:
|
||||||
|
# call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses=0]
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# declare i32 @llvm.bswap.i32(i32) nounwind readnone
|
||||||
|
#
|
||||||
|
|
||||||
|
# mysin(x) = sqrt(1.0 - pow(cos(x), 2))
|
||||||
|
|
||||||
|
float = Type.float()
|
||||||
|
mysinty = Type.function( float, [float] )
|
||||||
|
mysin = mod.add_function(mysinty, "mysin")
|
||||||
|
block = mysin.append_basic_block("entry")
|
||||||
|
b = Builder.new(block)
|
||||||
|
|
||||||
|
sqrt = Function.intrinsic(mod, INTR_SQRT, [float])
|
||||||
|
pow = Function.intrinsic(mod, INTR_POWI, [float])
|
||||||
|
cos = Function.intrinsic(mod, INTR_COS, [float])
|
||||||
|
|
||||||
|
mysin.args[0].name = "x"
|
||||||
|
x = mysin.args[0]
|
||||||
|
one = Constant.real(float, "1")
|
||||||
|
cosx = b.call(cos, [x], "cosx")
|
||||||
|
cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2")
|
||||||
|
onemc2 = b.sub(one, cos2, "onemc2")
|
||||||
|
sin = b.call(sqrt, [onemc2], "sin")
|
||||||
|
b.ret(sin)
|
||||||
|
print mod
|
||||||
|
|
||||||
|
#
|
||||||
|
# ; ModuleID = 'test'
|
||||||
|
#
|
||||||
|
# define void @showme() {
|
||||||
|
# entry:
|
||||||
|
# call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses=0]
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# declare i32 @llvm.bswap.i32(i32) nounwind readnone
|
||||||
|
#
|
||||||
|
# define float @mysin(float %x) {
|
||||||
|
# entry:
|
||||||
|
# %cosx = call float @llvm.cos.f32( float %x ) ; <float> [#uses=1]
|
||||||
|
# %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 ) ; <float> [#uses=1]
|
||||||
|
# %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses=1]
|
||||||
|
# %sin = call float @llvm.sqrt.f32( float %onemc2 ) ; <float> [#uses=1]
|
||||||
|
# ret float %sin
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# declare float @llvm.sqrt.f32(float) nounwind readnone
|
||||||
|
#
|
||||||
|
# declare float @llvm.powi.f32(float, i32) nounwind readnone
|
||||||
|
#
|
||||||
|
# declare float @llvm.cos.f32(float) nounwind readnone
|
||||||
|
#
|
||||||
|
|
@ -99,7 +99,7 @@ Steps
|
||||||
|
|
||||||
The commands illustrated below assume that the LLVM source is available
|
The commands illustrated below assume that the LLVM source is available
|
||||||
under +/home/mdevan/llvm+. If you've a previous version of llvm-py
|
under +/home/mdevan/llvm+. If you've a previous version of llvm-py
|
||||||
installed, you must remove it first, as described
|
installed, it is recommended to remove it first, as described
|
||||||
link:#uninstall[below].
|
link:#uninstall[below].
|
||||||
|
|
||||||
If you have +llvm-config+ in your path, you can build and install
|
If you have +llvm-config+ in your path, you can build and install
|
||||||
|
|
@ -130,7 +130,8 @@ $ 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
|
$ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
Be warned that debug binaries will be huge (65MB+) !
|
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
|
`setup.py` is a standard Python distutils script. See the Python
|
||||||
documentation regarding http://docs.python.org/inst/inst.html[Installing
|
documentation regarding http://docs.python.org/inst/inst.html[Installing
|
||||||
|
|
@ -302,8 +303,6 @@ to it's documentation.
|
||||||
|
|
||||||
include::instrset.inc[]
|
include::instrset.inc[]
|
||||||
|
|
||||||
Intrinsics (instructions that start with +llvm.+) are not yet available
|
|
||||||
in llvm-py.
|
|
||||||
|
|
||||||
Modules
|
Modules
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
@ -344,25 +343,7 @@ 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
|
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.)
|
||||||
|
|
||||||
Passes are run using a _pass manager_. TODO
|
[TODO: pass manager, execution engine, bit code]
|
||||||
|
|
||||||
|
|
||||||
Execution Engine
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
|
||||||
BitCode
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
|
||||||
llvm-gcc
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
|
||||||
The llvm-py Package
|
The llvm-py Package
|
||||||
|
|
@ -482,8 +463,28 @@ a Module object. This is a common feature for all llvm-py classes.
|
||||||
corresponding classes. Constructors _should not_ be used.
|
corresponding classes. Constructors _should not_ be used.
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
The argument `my_module` is a module identifier (a plain string). The
|
The argument `my_module` is a module identifier (a plain string). A
|
||||||
attributes of the `Module` class is:
|
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:
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# create a module from a bit code file
|
||||||
|
bcfile = file("test.bc")
|
||||||
|
my_module = Module.from_bitcode(bcfile)
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
There is corresponding serialization method also, called `to_bitcode`:
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# write out a bit code file from the module
|
||||||
|
bcfile = file("test.bc", "w")
|
||||||
|
my_module.to_bitcode(bcfile)
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.llvm.core.Module
|
.llvm.core.Module
|
||||||
[caption=""]
|
[caption=""]
|
||||||
|
|
@ -492,6 +493,9 @@ attributes of the `Module` class is:
|
||||||
`new(module_id)`::
|
`new(module_id)`::
|
||||||
Create a new `Module` instance with given `module_id`. The `module_id`
|
Create a new `Module` instance with given `module_id`. The `module_id`
|
||||||
should be a string.
|
should be a string.
|
||||||
|
`from_bitcode(fileobj)`::
|
||||||
|
Create a new `Module` instance by deserializing the bitcode file
|
||||||
|
represented by the file-like object `fileobj`.
|
||||||
|
|
||||||
.Properties
|
.Properties
|
||||||
`data_layout`::
|
`data_layout`::
|
||||||
|
|
@ -526,6 +530,9 @@ attributes of the `Module` class is:
|
||||||
`verify()`::
|
`verify()`::
|
||||||
Verify the correctness of the module. Raises `LLVMException` on
|
Verify the correctness of the module. Raises `LLVMException` on
|
||||||
errors.
|
errors.
|
||||||
|
`to_bitcode(fileobj)`::
|
||||||
|
Write the bitcode representation of the module to the file-like
|
||||||
|
object `fileobj`.
|
||||||
|
|
||||||
.Special Methods
|
.Special Methods
|
||||||
`\_\_str\_\_`::
|
`\_\_str\_\_`::
|
||||||
|
|
@ -630,9 +637,9 @@ The class-level documentation follows:
|
||||||
Creates an array type, holding `count` elements, each of type `elty`
|
Creates an array type, holding `count` elements, each of type `elty`
|
||||||
(which should be a `Type`).
|
(which should be a `Type`).
|
||||||
`pointer(pty, addrspc=0)`::
|
`pointer(pty, addrspc=0)`::
|
||||||
Create a pointer to type `pty` (which should be a `Type). `addrspc`
|
Create a pointer to type `pty` (which should be a `Type`). `addrspc`
|
||||||
is an integer that represents the address space of the pointer (see
|
is an integer that represents the address space of the pointer (see
|
||||||
LLVM docs / ask on llvm-dev for more info).
|
LLVM docs or ask on llvm-dev for more info).
|
||||||
`void()`::
|
`void()`::
|
||||||
Creates a void type. Used for function return types.
|
Creates a void type. Used for function return types.
|
||||||
`label()`::
|
`label()`::
|
||||||
|
|
@ -726,7 +733,6 @@ source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
`arg_count` [read-only]::
|
`arg_count` [read-only]::
|
||||||
The number of arguments. Same as `len(obj.args)`, but faster.
|
The number of arguments. Same as `len(obj.args)`, but faster.
|
||||||
|
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -831,8 +837,11 @@ intptr_ty = Type.pointer(int_ty) # "typedef int *intptr_ty;"
|
||||||
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
|
# 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, int_ty ] )
|
||||||
# functions that take 1 int_ty and return nothing
|
# functions that take 2 int_tys and return nothing
|
||||||
|
|
||||||
|
f3 = Type.function( Type.void(), ( int_ty, int_ty ) )
|
||||||
|
# same as f2; any iterable can be used
|
||||||
|
|
||||||
fnargs = [ Type.pointer( Type.int(8) ) ]
|
fnargs = [ Type.pointer( Type.int(8) ) ]
|
||||||
printf = Type.function( Type.int(), fnargs, True )
|
printf = Type.function( Type.int(), fnargs, True )
|
||||||
|
|
@ -840,6 +849,59 @@ printf = Type.function( Type.int(), fnargs, True )
|
||||||
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
TypeHandle (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
TypeHandle objects are used to create recursive types, like this linked
|
||||||
|
list node structure in C:
|
||||||
|
|
||||||
|
[C]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
struct node
|
||||||
|
{
|
||||||
|
int data;
|
||||||
|
struct node *next;
|
||||||
|
};
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This can be realized in llvm-py like this:
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
include::../../test/typehandle.py[]
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
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
|
||||||
|
Programmer's Manual section
|
||||||
|
http://llvm.org/docs/ProgrammersManual.html#TypeResolve["LLVM Type
|
||||||
|
Resolution"]. The TypeHandle class of llvm-py corresponds to
|
||||||
|
http://www.llvm.org/doxygen/classllvm_1_1PATypeHolder.html[`llvm::PATypeHolder`]
|
||||||
|
in C\+\+. The above example is available as
|
||||||
|
http://code.google.com/p/llvm-py/source/browse/trunk/test/typehandle.py[test/typehandle.py]
|
||||||
|
in the source distribution.
|
||||||
|
|
||||||
|
.llvm.core.TypeHandle
|
||||||
|
[caption=""]
|
||||||
|
=======================================================================
|
||||||
|
.Static Constructors
|
||||||
|
`new(abstract_ty)`::
|
||||||
|
create a new `TypeHandle` instance, which holds a reference to the
|
||||||
|
given abstract type `abstract_ty`. Typically, the abstract type used
|
||||||
|
is `Type.opaque()`.
|
||||||
|
|
||||||
|
.Properties
|
||||||
|
`type`::
|
||||||
|
returns the contained type. Typically the `refine` method is called
|
||||||
|
on the returned type.
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
|
||||||
Values (llvm.core)
|
Values (llvm.core)
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
@ -859,7 +921,7 @@ Value
|
||||||
CallOrInvokeInstruction
|
CallOrInvokeInstruction
|
||||||
PHINode
|
PHINode
|
||||||
SwitchInstruction
|
SwitchInstruction
|
||||||
BasicBlock
|
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.
|
||||||
|
|
@ -943,7 +1005,10 @@ Constructor Method, What It Creates
|
||||||
"`sizeof(ty)`", "Constant value representing the sizeof the type `ty`"
|
"`sizeof(ty)`", "Constant value representing the sizeof the type `ty`"
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The following operations are available:
|
The following operations on constants are supported. For more details on
|
||||||
|
any operation, consult the
|
||||||
|
http://www.llvm.org/docs/LangRef.html#constantexprs[Constant Expressions]
|
||||||
|
section of the LLVM Language Reference.
|
||||||
|
|
||||||
[[constops]]
|
[[constops]]
|
||||||
[frame="all",grid="all"]
|
[frame="all",grid="all"]
|
||||||
|
|
@ -973,19 +1038,19 @@ Method, Operation
|
||||||
`k.trunc(ty)`, "Truncate `k` to a type `ty` of lower bitwidth."
|
`k.trunc(ty)`, "Truncate `k` to a type `ty` of lower bitwidth."
|
||||||
`k.sext(ty)`, "Sign extend `k` to a type `ty` of higher bitwidth, while extending the sign bit."
|
`k.sext(ty)`, "Sign extend `k` to a type `ty` of higher bitwidth, while extending the sign bit."
|
||||||
`k.zext(ty)`, "Sign extend `k` to a type `ty` of higher bitwidth, all new bits are 0s."
|
`k.zext(ty)`, "Sign extend `k` to a type `ty` of higher bitwidth, all new bits are 0s."
|
||||||
fptrunc, TODO
|
`k.fptrunc(ty)`, "Truncate floating point constant `k` to floating point type `ty` of lower size than k's."
|
||||||
fpext, TODO
|
`k.fpext(ty)`, "Extend floating point constant `k` to floating point type `ty` of higher size than k's."
|
||||||
uitofp, TODO
|
`k.uitofp(ty)`, "Convert an unsigned integer constant `k` to floating point constant of type `ty`."
|
||||||
sitofp, TODO
|
`k.sitofp(ty)`, "Convert a signed integer constant `k` to floating point constant of type `ty`."
|
||||||
fptoui, TODO
|
`k.fptoui(ty)`, "Convert a floating point constant `k` to an unsigned integer constant of type `ty`."
|
||||||
fptosi, TODO
|
`k.fptosi(ty)`, "Convert a floating point constant `k` to a signed integer constant of type `ty`."
|
||||||
ptrtoint, TODO
|
`k.ptrtoint(ty)`, "Convert a pointer constant `k` to an integer constant of type `ty`."
|
||||||
inttoptr, TODO
|
`k.inttoptr(ty)`, "Convert an integer constant `k` to a pointer constant of type `ty`."
|
||||||
bitcast, TODO
|
`k.bitcast(ty)`, "Convert `k` to a (equal-width) constant of type `ty`."
|
||||||
select, TODO
|
"`k.select(cond,k2,k3)`", "Replace value with `k2` if the 1-bit integer constant `cond` is 1, else with `k3`."
|
||||||
extract_element, TODO
|
`k.extract_element(idx)`, "Extract value at `idx` (integer constant) from a vector constant `k`."
|
||||||
insert_element, TODO
|
"`k.insert_element(k2,idx)`", "Insert value `k2` (scalar constant) at index `idx` (integer constant) of vector constant `k`."
|
||||||
shuffle_vector, TODO
|
"`k.shuffle_vector(k2,mask)`", "Shuffle vector constant `k` based on vector constants `k2` and `mask`."
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[[ipred]]
|
[[ipred]]
|
||||||
|
|
@ -1049,73 +1114,395 @@ methods.
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
|
|
||||||
TypeHandle (llvm.core)
|
Global Value (llvm.core)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
TypeHandle objects are used to create recursive types, like this linked
|
The class `llvm.core.GlobalValue` represents module-scope aliases, variables
|
||||||
list node structure in C:
|
and functions. Global variables are represented by the sub-class
|
||||||
|
`llvm.core.GlobalVariable` and functions by `llvm.core.Function`.
|
||||||
|
|
||||||
[C]
|
Global values have the read-write properties `linkage`, `section`,
|
||||||
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
`visibility` and `alignment`. Use one of the following constants (from
|
||||||
struct node
|
llvm.core) as values for `linkage` (see
|
||||||
{
|
http://www.llvm.org/docs/LangRef.html#linkage[LLVM documentaion] for
|
||||||
int data;
|
details on each):
|
||||||
struct node *next;
|
|
||||||
};
|
|
||||||
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This can be realized in llvm-py like this:
|
[frame="all",grid="all"]
|
||||||
|
`25`75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Value, Equivalent LLVM Assembly Keyword
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
`LINKAGE_LINKONCE`, `linkonce`
|
||||||
|
`LINKAGE_WEAK`, `weak`
|
||||||
|
`LINKAGE_APPENDING`, `appending`
|
||||||
|
`LINKAGE_INTERNAL`, `internal`
|
||||||
|
`LINKAGE_DLLIMPORT`, `dllimport`
|
||||||
|
`LINKAGE_DLLEXPORT`, `dllexport`
|
||||||
|
`LINKAGE_EXTERNAL`, `externally visible`
|
||||||
|
`LINKAGE_EXTERNAL_WEAK`, `extern_weak`
|
||||||
|
`LINKAGE_GHOST`, Stand-in functions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
The `section` property can be assigned strings (like ".rodata"), which
|
||||||
include::../../test/typehandle.py[]
|
will be used if the target supports it. Visibility property can be set
|
||||||
-----------------------------------------------------------------------
|
to one of thse constants (from llvm.core, see also
|
||||||
|
http://www.llvm.org/docs/LangRef.html#visibility[LLVM docs]):
|
||||||
|
|
||||||
which gives the output:
|
[frame="all",grid="all"]
|
||||||
|
`25`75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Value, Equivalent LLVM Assembly Keyword
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
`VISIBILITY_DEFAULT`, `default`
|
||||||
|
`VISIBILITY_HIDDEN`, `hidden`
|
||||||
|
`VISIBILITY_PROTECTED`, `protected`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
The `alignment` property can be 0 (default), or can be set to a power of
|
||||||
; ModuleID = 'mod1'
|
2. The read-only property `is_declaration` can be used to check if the
|
||||||
%struct.node = type { i32, %struct.node* }
|
global is a declaration or not. The module to which the global belongs
|
||||||
-----------------------------------------------------------------------
|
to can be retrieved using the `module` property (read-only).
|
||||||
|
|
||||||
For more details on what is going on here, please refer the LLVM
|
.llvm.core.GlobalValue
|
||||||
Programmer's Manual section
|
|
||||||
http://llvm.org/docs/ProgrammersManual.html#TypeResolve["LLVM Type
|
|
||||||
Resolution"]. The TypeHandle class of llvm-py corresponds to
|
|
||||||
http://www.llvm.org/doxygen/classllvm_1_1PATypeHolder.html[`llvm::PATypeHolder`]
|
|
||||||
in C\+\+. The above example is available as
|
|
||||||
http://code.google.com/p/llvm-py/source/browse/trunk/test/typehandle.py[test/typehandle.py]
|
|
||||||
in the source distribution.
|
|
||||||
|
|
||||||
.llvm.core.TypeHandle
|
|
||||||
[caption=""]
|
[caption=""]
|
||||||
=======================================================================
|
=======================================================================
|
||||||
.Static Constructors
|
.Base Class
|
||||||
`new(abstract_ty)`::
|
- `llvm.core.Constant`
|
||||||
create a new `TypeHandle` instance, which holds a reference to the
|
|
||||||
given abstract type `abstract_ty`. Typically, the abstract type used
|
|
||||||
is `Type.opaque()`.
|
|
||||||
|
|
||||||
.Properties
|
.Properties
|
||||||
`type`::
|
`linkage`::
|
||||||
returns the contained type. Typically the `refine` method is called
|
The linkage type, takes one of the constants listed above
|
||||||
on the returned type.
|
(LINKAGE_*).
|
||||||
|
`section`::
|
||||||
|
A string like ".rodata", indicating the section into which the
|
||||||
|
global is placed into.
|
||||||
|
`visibility`::
|
||||||
|
The visibility type, takes one of the constants listed above
|
||||||
|
(VISIBILITY_*).
|
||||||
|
`alignment`::
|
||||||
|
A power-of-2 integer indicating the boundary to align to.
|
||||||
|
`is_declaration` [read-only]::
|
||||||
|
`True` if the global is a declaration, `False` otherwise.
|
||||||
|
`module` [read-only]::
|
||||||
|
The module object to which this global belongs to.
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
Global Variable (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# create a global variable using add_global_variable method
|
||||||
|
gv1 = module_obj.add_global_variable(Type.int(), "gv1")
|
||||||
|
|
||||||
|
# or equivalently, using a static constructor method
|
||||||
|
gv2 = GlobalVariable.new(module_obj, Type.int(), "gv2")
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# retrieve a reference to the global variable gv1,
|
||||||
|
# using the get_global_variable_named method
|
||||||
|
gv1 = module_obj.get_global_variable_named("gv1")
|
||||||
|
|
||||||
|
# or equivalently, using the static `get` method:
|
||||||
|
gv2 = GlobalVariable.get(module_obj, "gv2")
|
||||||
|
|
||||||
|
# list all global variables in a module
|
||||||
|
for gv in module_obj.global_variables:
|
||||||
|
print gv.name, "of type", gv.type
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# add an initializer 10 (32-bit integer)
|
||||||
|
gv.initializer = Constant.int( Type.int(), 10 )
|
||||||
|
|
||||||
|
# delete the global
|
||||||
|
gv.delete()
|
||||||
|
# DO NOT dereference `gv' beyond this point!
|
||||||
|
gv = None
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.llvm.core.GlobalVariable
|
||||||
|
[caption=""]
|
||||||
|
=======================================================================
|
||||||
|
.Base Class
|
||||||
|
- `llvm.core.GlobalValue`
|
||||||
|
|
||||||
|
.Static Constructors
|
||||||
|
`new(module_obj, ty, name)`::
|
||||||
|
Create a global variable named `name` of type `ty` in the module
|
||||||
|
`module_obj` and return a `GlobalVariable` object that represents it.
|
||||||
|
`get(module_obj, name)`::
|
||||||
|
Return a `GlobalVariable` object to represent the global variable
|
||||||
|
named `name` in the module `module_obj` or raise `LLVMException` if
|
||||||
|
such a variable does not exist.
|
||||||
|
|
||||||
|
.Properties
|
||||||
|
`initializer`::
|
||||||
|
The intializer of the variable. Set to `llvm.core.Constant` (or
|
||||||
|
derived). Gets the initializer constant, or `None` if none exists.
|
||||||
|
`global_constant`::
|
||||||
|
`True` if the variable is a global constant, `False` otherwise.
|
||||||
|
|
||||||
|
.Methods
|
||||||
|
`delete()`::
|
||||||
|
Deletes the global variable from it's module. _Do not hold any
|
||||||
|
references to this object after calling `delete` on it._
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
Function (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# create a type, representing functions that take an integer and return
|
||||||
|
# a floating point value.
|
||||||
|
ft = Type.function( Type.float(), [ Type.int() ] )
|
||||||
|
|
||||||
|
# create a function of this type
|
||||||
|
f1 = module_obj.add_function(ft, "func1")
|
||||||
|
|
||||||
|
# or equivalently, like this:
|
||||||
|
f2 = Function.new(module_obj, ft, "func2")
|
||||||
|
|
||||||
|
# get a reference to an existing function
|
||||||
|
f3 = module_obj.get_function_named("func3")
|
||||||
|
|
||||||
|
# or like this:
|
||||||
|
f4 = Function.get(module_obj, "func4")
|
||||||
|
|
||||||
|
# list all function names in a module
|
||||||
|
for f in module_obj.functions:
|
||||||
|
print f.name
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# get a reference to the llvm.bswap intrinsic
|
||||||
|
bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()])
|
||||||
|
|
||||||
|
# call it
|
||||||
|
builder.call(bswap, [value])
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Here, the constant `INTR_BSWAP`, available from `llvm.core`, represents
|
||||||
|
the LLVM intrinsic
|
||||||
|
http://www.llvm.org/docs/LangRef.html#int_bswap[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:
|
||||||
|
|
||||||
|
[frame="all",grid="all"]
|
||||||
|
`33`33`33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
INTR_ANNOTATION,INTR_DBG_STOPPOINT,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_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_OR,INTR_EH_TYPEID_FOR_I64,INTR_READCYCLECOUNTER
|
||||||
|
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_MEMSET_I32,
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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
|
||||||
|
http://code.google.com/p/llvm-py/source/browse/trunk/llvm/core.py[`core.py`].
|
||||||
|
See the http://www.llvm.org/docs/LangRef.html[LLVM Language Reference]
|
||||||
|
for more information on the intrinsics, and the
|
||||||
|
http://code.google.com/p/llvm-py/source/browse#svn/trunk/test[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
|
||||||
|
`calling_convention` property. The following (integer) constants defined
|
||||||
|
in `llvm.core` can be used as values:
|
||||||
|
|
||||||
|
[frame="all",grid="all"]
|
||||||
|
`25`75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Value, Equivalent LLVM Assembly Keyword
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
`CC_C`, `ccc`
|
||||||
|
`CC_FASTCALL`, `fastcc`
|
||||||
|
`CC_COLDCALL`, `coldcc`
|
||||||
|
`CC_X86_STDCALL`, ?
|
||||||
|
`CC_X86_FASTCALL`, `fastcc`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See the http://www.llvm.org/docs/LangRef.html#callingconv[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
|
||||||
|
got using the read-only property `args`. These can be iterated over, and
|
||||||
|
also be indexed via integers. An example:
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# list all argument names and types
|
||||||
|
for arg in fn.args:
|
||||||
|
print arg.name, "of type", arg.type
|
||||||
|
|
||||||
|
# change the name of the first argument
|
||||||
|
fn.args[0].name = "objptr"
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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
|
||||||
|
of the function can be retrieved using the `get_entry_basic_block`
|
||||||
|
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)`.
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# add a basic block
|
||||||
|
b1 = fn.append_basic_block("entry")
|
||||||
|
|
||||||
|
# get the first one
|
||||||
|
b2 = fn.get_entry_basic_block()
|
||||||
|
b2 = fn.basic_blocks[0] # slower than previous method
|
||||||
|
|
||||||
|
# print names of all basic blocks
|
||||||
|
for b in fn.basic_blocks:
|
||||||
|
print b.name
|
||||||
|
|
||||||
|
# get number of basic blocks
|
||||||
|
n = fn.basic_block_count
|
||||||
|
n = len(fn.basic_blocks) # slower than previous method
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
Argument (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
[frame="all",grid="all"]
|
||||||
|
`25`75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Value, Equivalent LLVM Assembly Keyword
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
`ATTR_ZEXT`, `zeroext`
|
||||||
|
`ATTR_SEXT`, `signext`
|
||||||
|
`ATTR_NO_RETURN`, `noreturn`
|
||||||
|
`ATTR_IN_REG`, `inreg`
|
||||||
|
`ATTR_STRUCT_RET`, `sret`
|
||||||
|
`ATTR_NO_UNWIND`, `nounwind`
|
||||||
|
`ATTR_NO_ALIAS`, `noalias`
|
||||||
|
`ATTR_BY_VAL`, `byval`
|
||||||
|
`ATTR_NEST`, `nest`
|
||||||
|
`ATTR_READ_NONE`, `readnone`
|
||||||
|
`ATTR_READONLY`, `readonly`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The corresponding
|
||||||
|
file:///home/mdevan/llvm-2.3/docs/LangRef.html#paramattrs[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.
|
||||||
|
|
||||||
|
Basic Block (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The class `llvm.core.BasicBlock` represents a basic block of
|
||||||
|
instructions. Basic blocks are logically contained within functions, and
|
||||||
|
can be constructed only via `Function` objects. Use the
|
||||||
|
`Function.append_basic_block()` method for this:
|
||||||
|
|
||||||
|
[python]
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# create a function
|
||||||
|
func = module.add_function(functy, "fn")
|
||||||
|
# add a basic block, named 'entry', to the function
|
||||||
|
bblk = func.append_basic_block("entry")
|
||||||
|
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The list of all
|
||||||
|
|
||||||
|
|
||||||
|
Builder (llvm.core)
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
|
||||||
Instructions (llvm.core)
|
Instructions (llvm.core)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
TODO
|
The class `llvm.core.Instruction` represents an LLVM IR instruction.
|
||||||
|
Instruction objects can be created only via a builder.
|
||||||
|
|
||||||
Basic Block (llvm.core)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
|
||||||
Builder (llvm.core)
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
@ -1126,14 +1513,14 @@ Module Provider (llvm.core)
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
||||||
Execution Engine (llvm.ee)
|
Target Data (llvm.ee)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
||||||
Target Data (llvm.ee)
|
Execution Engine (llvm.ee)
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
@ -1144,13 +1531,6 @@ Pass Managers and Passes (llvm.passes)
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
||||||
[[examples]]
|
|
||||||
Annotated Examples
|
|
||||||
------------------
|
|
||||||
|
|
||||||
include::example.inc[]
|
|
||||||
|
|
||||||
|
|
||||||
About the llvm-py Project
|
About the llvm-py Project
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue