New tests. Code cleanup.
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@11 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
parent
117dc747de
commit
274f0f9ec4
16 changed files with 638 additions and 113 deletions
|
|
@ -12,6 +12,7 @@
|
|||
* Python doc string documentation added (still incomplete)
|
||||
* Many minor style/cosmetic changes and bug fixes
|
||||
* Added documentation as on website into SVN
|
||||
* Lots of cleanup
|
||||
|
||||
|
||||
0.1, 10-May-2008:
|
||||
|
|
|
|||
15
README
15
README
|
|
@ -2,28 +2,23 @@
|
|||
llvm-py: Python Bindings for LLVM
|
||||
---------------------------------
|
||||
|
||||
llvm-py provides Python bindings for LLVM.
|
||||
|
||||
|
||||
Home page:
|
||||
----------
|
||||
http://mdevan.nfshost.com/llvm-py.html
|
||||
http://code.google.com/p/llvm-py/
|
||||
http://mdevan.nfshost.com/llvm-py/
|
||||
|
||||
|
||||
Quickstart:
|
||||
----------
|
||||
1. Get 2.3svn version of LLVM, build it. 2.2 or earlier will *not* work.
|
||||
LLVM need not be installed.
|
||||
1. Get 2.3 version of LLVM, build it. 2.2 or earlier will *not* work.
|
||||
|
||||
2. Unpack llvm-py, build and install:
|
||||
|
||||
$ tar jxvf llvm-py-0.2.tar.bz2
|
||||
$ cd llvm-py-0.2
|
||||
|
||||
# if you've installed LLVM, and llvm-config is in the path
|
||||
$ sudo python setup.py install
|
||||
|
||||
# if you've just built LLVM and not installed it, locate llvm-config,
|
||||
# usually under ../llvm/Release/bin
|
||||
# Locate llvm-config, usually under <llvm>/Release/bin
|
||||
$ sudo python setup.py install --llvm-config=/path/to/llvm-config
|
||||
|
||||
3. See examples under 'test' directory.
|
||||
|
|
|
|||
37
llvm/_core.c
37
llvm/_core.c
|
|
@ -355,7 +355,20 @@ _wrap_obj2obj(LLVMGetFunctionCallConv, LLVMValueRef, int)
|
|||
_wrap_objint2none(LLVMSetFunctionCallConv, LLVMValueRef)
|
||||
_wrap_obj2str(LLVMGetCollector, LLVMValueRef)
|
||||
_wrap_objstr2none(LLVMSetCollector, LLVMValueRef)
|
||||
_wrap_objint2obj(LLVMVerifyFunction, LLVMValueRef, int)
|
||||
|
||||
static PyObject *
|
||||
_wLLVMVerifyFunction(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *obj;
|
||||
LLVMValueRef fn;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &obj))
|
||||
return NULL;
|
||||
|
||||
fn = (LLVMValueRef) PyCObject_AsVoidPtr(obj);
|
||||
return ctor_int(LLVMVerifyFunction(fn, LLVMReturnStatusAction));
|
||||
}
|
||||
|
||||
|
||||
/*===-- Arguments --------------------------------------------------------===*/
|
||||
|
||||
|
|
@ -407,27 +420,6 @@ _wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef)
|
|||
/*===-- Instruction builders ----------------------------------------------===*/
|
||||
|
||||
_wrap_none2obj(LLVMCreateBuilder, LLVMBuilderRef)
|
||||
|
||||
static PyObject *
|
||||
_wLLVMPositionBuilder(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *obj1, *obj2, *obj3 = 0;
|
||||
LLVMBuilderRef builder;
|
||||
LLVMBasicBlockRef block;
|
||||
LLVMValueRef instr = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO|O", &obj1, &obj2, &obj3))
|
||||
return NULL;
|
||||
|
||||
builder = (LLVMBuilderRef) (PyCObject_AsVoidPtr(obj1));
|
||||
block = (LLVMBasicBlockRef)(PyCObject_AsVoidPtr(obj2));
|
||||
if (obj3) /* optional */
|
||||
instr = (LLVMValueRef)(PyCObject_AsVoidPtr(obj3));
|
||||
|
||||
LLVMPositionBuilder(builder, block, instr);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
_wrap_objobj2none(LLVMPositionBuilderBefore, LLVMBuilderRef, LLVMValueRef)
|
||||
_wrap_objobj2none(LLVMPositionBuilderAtEnd, LLVMBuilderRef, LLVMBasicBlockRef)
|
||||
_wrap_obj2obj(LLVMGetInsertBlock, LLVMBuilderRef, LLVMBasicBlockRef)
|
||||
|
|
@ -946,7 +938,6 @@ static PyMethodDef core_methods[] = {
|
|||
|
||||
/* Instruction builders */
|
||||
_method( LLVMCreateBuilder )
|
||||
_method( LLVMPositionBuilder )
|
||||
_method( LLVMPositionBuilderBefore )
|
||||
_method( LLVMPositionBuilderAtEnd )
|
||||
_method( LLVMGetInsertBlock )
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import llvm
|
|||
|
||||
def _check_gen(obj, type):
|
||||
if not isinstance(obj, type):
|
||||
type_str = type.__name__
|
||||
msg = "argument not an instance of llvm.core.%s" % type_str
|
||||
raise TypeError, msg
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ def unpack_constants(objlist): return _unpack_gen(objlist, check_is_constant)
|
|||
# we now return a list.
|
||||
#===----------------------------------------------------------------------===
|
||||
|
||||
def wrapiter(first, next, container, wrapper):
|
||||
def wrapiter(first, next, container, wrapper, extra=[]):
|
||||
# ptr = first(container)
|
||||
# while ptr:
|
||||
# yield wrapper(ptr)
|
||||
|
|
@ -59,7 +60,7 @@ def wrapiter(first, next, container, wrapper):
|
|||
ret = []
|
||||
ptr = first(container)
|
||||
while ptr:
|
||||
ret.append(wrapper(ptr))
|
||||
ret.append(wrapper(ptr, *extra))
|
||||
ptr = next(ptr)
|
||||
return ret
|
||||
|
||||
|
|
|
|||
193
llvm/core.py
193
llvm/core.py
|
|
@ -132,9 +132,6 @@ class Module(llvm.Ownable):
|
|||
"""
|
||||
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule)
|
||||
|
||||
def __del__(self):
|
||||
llvm.Ownable.__del__(self)
|
||||
|
||||
def __str__(self):
|
||||
"""Text representation of a module.
|
||||
|
||||
|
|
@ -212,7 +209,7 @@ class Module(llvm.Ownable):
|
|||
# do stuff with gv
|
||||
"""
|
||||
return wrapiter(_core.LLVMGetFirstGlobal, _core.LLVMGetNextGlobal,
|
||||
self.ptr, GlobalVariable)
|
||||
self.ptr, GlobalVariable, [self])
|
||||
|
||||
def add_function(self, ty, name):
|
||||
"""Add a function of given type with given name."""
|
||||
|
|
@ -233,9 +230,13 @@ class Module(llvm.Ownable):
|
|||
# do stuff with f
|
||||
"""
|
||||
return wrapiter(_core.LLVMGetFirstFunction,
|
||||
_core.LLVMGetNextFunction, self.ptr, Function)
|
||||
_core.LLVMGetNextFunction, self.ptr, Function, [self])
|
||||
|
||||
def verify(self):
|
||||
"""Verify module.
|
||||
|
||||
Checks module for errors. Raises `llvm.LLVMException' on any
|
||||
error."""
|
||||
ret = _core.LLVMVerifyModule(self.ptr)
|
||||
if ret != "":
|
||||
raise llvm.LLVMException, ret
|
||||
|
|
@ -267,6 +268,7 @@ class Type(object):
|
|||
elif bits == 64:
|
||||
return _make_type(_core.LLVMInt64Type(), TYPE_INTEGER)
|
||||
else:
|
||||
bits = int(bits) # bits must be an int
|
||||
return _make_type(_core.LLVMIntType(bits), TYPE_INTEGER)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -306,7 +308,8 @@ class Type(object):
|
|||
check_is_type(return_ty)
|
||||
var_arg = 1 if var_arg else 0 # convert to int
|
||||
params = unpack_types(param_tys)
|
||||
return _make_type(_core.LLVMFunctionType(return_ty.ptr, params, var_arg), TYPE_FUNCTION)
|
||||
return _make_type(_core.LLVMFunctionType(return_ty.ptr, params,
|
||||
var_arg), TYPE_FUNCTION)
|
||||
|
||||
@staticmethod
|
||||
def struct(element_tys): # not packed
|
||||
|
|
@ -314,7 +317,7 @@ class Type(object):
|
|||
|
||||
Creates a structure type with elements of types as given in the
|
||||
iterable `element_tys'. This method creates a unpacked
|
||||
structure. For a packed one, use packed_struct() method."""
|
||||
structure. For a packed one, use the packed_struct() method."""
|
||||
elems = unpack_types(element_tys)
|
||||
return _make_type(_core.LLVMStructType(elems, 0), TYPE_STRUCT)
|
||||
|
||||
|
|
@ -324,42 +327,77 @@ class Type(object):
|
|||
|
||||
Creates a structure type with elements of types as given in the
|
||||
iterable `element_tys'. This method creates a packed
|
||||
structure. For an unpacked one, use struct() method."""
|
||||
structure. For an unpacked one, use the struct() method."""
|
||||
elems = unpack_types(element_tys)
|
||||
return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT)
|
||||
|
||||
@staticmethod
|
||||
def array(element_ty, count):
|
||||
"""Create an array type.
|
||||
|
||||
Creates a type for an array of elements of type `element_ty',
|
||||
having 'count' elements."""
|
||||
check_is_type(element_ty)
|
||||
return _make_type(_core.LLVMArrayType(element_ty.ptr, count), TYPE_ARRAY)
|
||||
count = int(count) # must be an int
|
||||
return _make_type(_core.LLVMArrayType(element_ty.ptr, count),
|
||||
TYPE_ARRAY)
|
||||
|
||||
@staticmethod
|
||||
def pointer(pointee_ty, addr_space=0):
|
||||
"""Create a pointer type.
|
||||
|
||||
Creates a pointer type, which can point to values of type
|
||||
`pointee_ty', in the address space `addr_space'."""
|
||||
check_is_type(pointee_ty)
|
||||
return _make_type(_core.LLVMPointerType(pointee_ty.ptr, addr_space), TYPE_POINTER)
|
||||
addr_space = int(addr_space) # must be an int
|
||||
return _make_type(_core.LLVMPointerType(pointee_ty.ptr,
|
||||
addr_space), TYPE_POINTER)
|
||||
|
||||
@staticmethod
|
||||
def vector(element_ty, count):
|
||||
"""Create a vector type.
|
||||
|
||||
Creates a type for a vector of elements of type `element_ty',
|
||||
having `count' elements."""
|
||||
check_is_type(element_ty)
|
||||
return _make_type(_core.LLVMVectorType(element_ty.ptr, count), TYPE_VECTOR)
|
||||
count = int(count) # must be an int
|
||||
return _make_type(_core.LLVMVectorType(element_ty.ptr, count),
|
||||
TYPE_VECTOR)
|
||||
|
||||
@staticmethod
|
||||
def void():
|
||||
"""Create a void type.
|
||||
|
||||
Represents the `void' type."""
|
||||
return _make_type(_core.LLVMVoidType(), TYPE_VOID)
|
||||
|
||||
@staticmethod
|
||||
def label():
|
||||
"""Create a label type."""
|
||||
return _make_type(_core.LLVMLabelType(), TYPE_LABEL)
|
||||
|
||||
@staticmethod
|
||||
def opaque():
|
||||
"""Create an opaque type.
|
||||
|
||||
Opaque types are used to create self-referencing types."""
|
||||
return _make_type(_core.LLVMOpaqueType(), TYPE_OPAQUE)
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods instead."""
|
||||
self.ptr = ptr
|
||||
self.kind = kind
|
||||
"""An enum (int) value denoting which type this is.
|
||||
|
||||
Use the symbolic constants TYPE_* defined in llvm.core
|
||||
module."""
|
||||
|
||||
def __str__(self):
|
||||
"""Text representation of a type.
|
||||
|
||||
Returns the textual representation (`llvm assembly') of the type."""
|
||||
return _core.LLVMDumpTypeToString(self.ptr)
|
||||
|
||||
def __eq__(self, rhs):
|
||||
|
|
@ -369,10 +407,10 @@ class Type(object):
|
|||
return False
|
||||
|
||||
def refine(self, dest):
|
||||
"""Refine the abstract type represented by self to a concrete class.
|
||||
"""Refine the abstract type represented by self into a concrete class.
|
||||
|
||||
This object is no longer valid after refining, so do not hold references
|
||||
to it after calling."""
|
||||
to it after calling. See the user guide for examples on how to use this."""
|
||||
|
||||
check_is_type(dest)
|
||||
_core.LLVMRefineType(self.ptr, dest.ptr)
|
||||
|
|
@ -380,43 +418,62 @@ class Type(object):
|
|||
|
||||
|
||||
class IntegerType(Type):
|
||||
"""Represents an integer type."""
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
"""The width of the integer type, in bits."""
|
||||
return _core.LLVMGetIntTypeWidth(self.ptr)
|
||||
|
||||
|
||||
class FunctionType(Type):
|
||||
"""Represents a function type."""
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
def return_type(self):
|
||||
"""The type of the value returned by this function."""
|
||||
ptr = _core.LLVMGetReturnType(self.ptr)
|
||||
kind = _core.LLVMGetTypeKind(ptr)
|
||||
return _make_type(ptr, kind)
|
||||
|
||||
@property
|
||||
def vararg(self):
|
||||
"""True if this function is variadic."""
|
||||
return _core.LLVMIsFunctionVarArg(self.ptr) != 0
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""An iterable that yields Type objects, representing the types of the
|
||||
arguments accepted by this function, in order."""
|
||||
pp = _core.LLVMGetFunctionTypeParams(self.ptr)
|
||||
return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ]
|
||||
|
||||
@property
|
||||
def arg_count(self):
|
||||
"""Number of arguments accepted by this function.
|
||||
|
||||
Same as len(obj.args), but faster."""
|
||||
return _core.LLVMCountParamTypes(self.ptr)
|
||||
|
||||
|
||||
class StructType(Type):
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
|
|
@ -436,6 +493,9 @@ class StructType(Type):
|
|||
class ArrayType(Type):
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
|
|
@ -452,6 +512,9 @@ class ArrayType(Type):
|
|||
class PointerType(Type):
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
|
|
@ -462,6 +525,9 @@ class PointerType(Type):
|
|||
class VectorType(Type):
|
||||
|
||||
def __init__(self, ptr, kind):
|
||||
"""DO NOT CALL DIRECTLY.
|
||||
|
||||
Use one of the static methods of the *base* class (Type) instead."""
|
||||
Type.__init__(self, ptr, kind)
|
||||
|
||||
@property
|
||||
|
|
@ -602,12 +668,12 @@ class Constant(Value):
|
|||
@staticmethod
|
||||
def struct(consts): # not packed
|
||||
const_ptrs = unpack_constants(consts)
|
||||
return Constant(_core.LLVMConstStruct(consts, 0))
|
||||
return Constant(_core.LLVMConstStruct(const_ptrs, 0))
|
||||
|
||||
@staticmethod
|
||||
def packed_struct(consts):
|
||||
const_ptrs = unpack_constants(consts)
|
||||
return Constant(_core.LLVMConstStruct(consts, 1))
|
||||
return Constant(_core.LLVMConstStruct(const_ptrs, 1))
|
||||
|
||||
@staticmethod
|
||||
def vector(consts):
|
||||
|
|
@ -770,7 +836,7 @@ class Constant(Value):
|
|||
check_is_constant(index)
|
||||
return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr))
|
||||
|
||||
def shuffle_element(self, vector_b, mask): # note: self must be a _vector_ constant
|
||||
def shuffle_vector(self, vector_b, mask): # note: self must be a _vector_ constant
|
||||
check_is_constant(vector_b) # note: vector_b must be a _vector_ constant
|
||||
check_is_constant(mask)
|
||||
return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr))
|
||||
|
|
@ -778,8 +844,13 @@ class Constant(Value):
|
|||
|
||||
class GlobalValue(Constant):
|
||||
|
||||
def __init__(self, ptr):
|
||||
def __init__(self, ptr, module):
|
||||
Constant.__init__(self, ptr)
|
||||
self._module = module # hang on to the module
|
||||
|
||||
def _delete(self):
|
||||
self._module = None # set it free
|
||||
self.ptr = None
|
||||
|
||||
def get_linkage(self): return _core.LLVMGetLinkage(self.ptr)
|
||||
def set_linkage(self, value): _core.LLVMSetLinkage(self.ptr, value)
|
||||
|
|
@ -799,13 +870,11 @@ class GlobalValue(Constant):
|
|||
|
||||
@property
|
||||
def is_declaration(self):
|
||||
return _core.LLVMIsDeclaration(self.ptr)
|
||||
return _core.LLVMIsDeclaration(self.ptr) != 0
|
||||
|
||||
@property
|
||||
def module(self):
|
||||
mod = Module(_core.LLVMGetGlobalParent(self.ptr))
|
||||
owner = dummy_owner(mod)
|
||||
return mod
|
||||
return self._module
|
||||
|
||||
|
||||
class GlobalVariable(GlobalValue):
|
||||
|
|
@ -813,18 +882,18 @@ class GlobalVariable(GlobalValue):
|
|||
@staticmethod
|
||||
def new(module, ty, name):
|
||||
check_is_type(ty)
|
||||
return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name))
|
||||
return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name), module)
|
||||
|
||||
@staticmethod
|
||||
def get(module, name):
|
||||
return GlobalVariable(_core.LLVMGetNamedGlobal(module.ptr, name))
|
||||
return GlobalVariable(_core.LLVMGetNamedGlobal(module.ptr, name), module)
|
||||
|
||||
def __init__(self, ptr):
|
||||
GlobalValue.__init__(self, ptr)
|
||||
def __init__(self, ptr, module):
|
||||
GlobalValue.__init__(self, ptr, module)
|
||||
|
||||
def delete(self):
|
||||
_core.LLVMDeleteGlobal(self.ptr)
|
||||
self.ptr = None
|
||||
self._delete()
|
||||
|
||||
def get_initializer(self):
|
||||
if _core.LLVMHasInitializer(self.ptr):
|
||||
|
|
@ -862,27 +931,23 @@ class Argument(Value):
|
|||
def set_alignment(self, align):
|
||||
_core.LLVMSetParamAlignment(self.ptr, align)
|
||||
|
||||
@property
|
||||
def function(self):
|
||||
return Function(_core.LLVMGetParamParent(self.ptr))
|
||||
|
||||
|
||||
class Function(GlobalValue):
|
||||
|
||||
@staticmethod
|
||||
def new(module, func_ty, name):
|
||||
return Function(_core.LLVMAddFunction(module.ptr, name, func_ty.ptr))
|
||||
return Function(_core.LLVMAddFunction(module.ptr, name, func_ty.ptr), module)
|
||||
|
||||
@staticmethod
|
||||
def get(module, name):
|
||||
return Function(_core.LLVMGetNamedFunction(module.ptr, name))
|
||||
return Function(_core.LLVMGetNamedFunction(module.ptr, name), module)
|
||||
|
||||
def __init__(self, ptr):
|
||||
GlobalValue.__init__(self, ptr)
|
||||
def __init__(self, ptr, module):
|
||||
GlobalValue.__init__(self, ptr, module)
|
||||
|
||||
def delete(self):
|
||||
_core.LLVMDeleteFunction(self.ptr)
|
||||
self.ptr = None
|
||||
self._delete()
|
||||
|
||||
@property
|
||||
def intrinsic_id(self):
|
||||
|
|
@ -906,6 +971,8 @@ class Function(GlobalValue):
|
|||
return _core.LLVMCountBasicBlocks(self.ptr)
|
||||
|
||||
def get_entry_basic_block(self):
|
||||
if self.basic_block_count == 0:
|
||||
return None
|
||||
return BasicBlock(_core.LLVMGetEntryBasicBlock(self.ptr))
|
||||
|
||||
def append_basic_block(self, name):
|
||||
|
|
@ -917,6 +984,8 @@ class Function(GlobalValue):
|
|||
_core.LLVMGetNextBasicBlock, self.ptr, BasicBlock)
|
||||
|
||||
def verify(self):
|
||||
# Although we're just asking LLVM to return the success or
|
||||
# failure, it appears to print result to stderr and abort.
|
||||
return _core.LLVMVerifyFunction(self.ptr) != 0
|
||||
|
||||
|
||||
|
|
@ -939,8 +1008,8 @@ class CallOrInvokeInstruction(Instruction):
|
|||
def __init__(self, ptr):
|
||||
Instruction.__init__(self, ptr)
|
||||
|
||||
def get_calling_convention(self): return _core.LLVMGetFunctionCallConv(self.ptr)
|
||||
def set_calling_convention(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value)
|
||||
def get_calling_convention(self): return _core.LLVMGetInstructionCallConv(self.ptr)
|
||||
def set_calling_convention(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value)
|
||||
calling_convention = property(get_calling_convention, set_calling_convention)
|
||||
|
||||
def add_parameter_attribute(self, idx, attr):
|
||||
|
|
@ -1020,8 +1089,11 @@ class BasicBlock(Value):
|
|||
class Builder(object):
|
||||
|
||||
@staticmethod
|
||||
def new():
|
||||
return Builder(_core.LLVMCreateBuilder())
|
||||
def new(basic_block):
|
||||
check_is_basic_block(basic_block)
|
||||
b = Builder(_core.LLVMCreateBuilder())
|
||||
b.position_at_end(basic_block)
|
||||
return b
|
||||
|
||||
def __init__(self, ptr):
|
||||
self.ptr = ptr
|
||||
|
|
@ -1029,22 +1101,34 @@ class Builder(object):
|
|||
def __del__(self):
|
||||
_core.LLVMDisposeBuilder(self.ptr)
|
||||
|
||||
def position(self, block, instr=None):
|
||||
if instr:
|
||||
_core.LLVMPositionBuilder(self.ptr, block.ptr, instr.ptr)
|
||||
else:
|
||||
_core.LLVMPositionBuilder(self.ptr, block.ptr)
|
||||
|
||||
def position_before(self, instr):
|
||||
_core.LLVMPositionBuilderBefore(self.ptr, instr.ptr)
|
||||
def position_at_beginning(self, bblk):
|
||||
"""Position the builder at the beginning of the given block.
|
||||
|
||||
Next instruction inserted will be first one in the block."""
|
||||
# Avoids using "blk.instructions", which will fetch all the
|
||||
# instructions into a list. Don't try this at home, though.
|
||||
first_inst = Instruction(_core.LLVMGetFirstInstruction(self.block.ptr))
|
||||
self.position_before(first_inst)
|
||||
|
||||
def position_at_end(self, bblk):
|
||||
"""Position the builder at the end of the given block.
|
||||
|
||||
Next instruction inserted will be last one in the block."""
|
||||
_core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr)
|
||||
|
||||
def position_before(self, instr):
|
||||
"""Position the builder before the given instruction.
|
||||
|
||||
The instruction can belong to a basic block other than the
|
||||
current one."""
|
||||
_core.LLVMPositionBuilderBefore(self.ptr, instr.ptr)
|
||||
|
||||
@property
|
||||
def insert_block(self):
|
||||
def block(self):
|
||||
return BasicBlock(_core.LLVMGetInsertBlock(self.ptr))
|
||||
|
||||
# terminator instructions
|
||||
|
||||
def ret_void(self):
|
||||
return Instruction(_core.LLVMBuildRetVoid(self.ptr))
|
||||
|
||||
|
|
@ -1084,7 +1168,7 @@ class Builder(object):
|
|||
def unreachable(self):
|
||||
return Instruction(_core.LLVMBuildUnreachable(self.ptr))
|
||||
|
||||
# arithmethic-related
|
||||
# arithmethic, bitwise and logical
|
||||
|
||||
def add(self, lhs, rhs, name=""):
|
||||
check_is_value(lhs)
|
||||
|
|
@ -1207,7 +1291,7 @@ class Builder(object):
|
|||
index_ptrs = unpack_values(indices)
|
||||
return Value(_core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name))
|
||||
|
||||
# casts
|
||||
# casts and extensions
|
||||
|
||||
def trunc(self, value, dest_ty, name=""):
|
||||
check_is_value(value)
|
||||
|
|
@ -1306,11 +1390,11 @@ class Builder(object):
|
|||
arg_ptrs = unpack_values(args)
|
||||
return CallOrInvokeInstruction(_core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name))
|
||||
|
||||
def select(self, if_blk, then_blk, else_blk, name=""):
|
||||
check_is_basic_block(if_blk)
|
||||
def select(self, cond, then_blk, else_blk, name=""):
|
||||
check_is_value(cond)
|
||||
check_is_basic_block(then_blk)
|
||||
check_is_basic_block(else_blk)
|
||||
return Value(_core.LLVMBuildSelect(self.ptr, if_blk.ptr, then_blk.ptr, else_blk.ptr, name))
|
||||
return Value(_core.LLVMBuildSelect(self.ptr, cond.ptr, then_blk.ptr, else_blk.ptr, name))
|
||||
|
||||
def vaarg(self, list_val, ty, name=""):
|
||||
check_is_value(list_val)
|
||||
|
|
@ -1356,9 +1440,6 @@ class ModuleProvider(llvm.Ownable):
|
|||
# a module provider is both a owner (of modules) and an ownable
|
||||
# (can be owned by execution engines)
|
||||
|
||||
def __del__(self):
|
||||
llvm.Ownable.__del__(self)
|
||||
|
||||
|
||||
#===----------------------------------------------------------------------===
|
||||
# Memory buffer
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@ class TargetData(llvm.Ownable):
|
|||
def __init__(self, ptr):
|
||||
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetData)
|
||||
|
||||
def __del__(self):
|
||||
llvm.Ownable.__del__(self)
|
||||
|
||||
def __str__(self):
|
||||
return _core.LLVMTargetDataAsString(self.ptr)
|
||||
|
||||
|
|
|
|||
|
|
@ -78,9 +78,6 @@ class FunctionPassManager(PassManager):
|
|||
def __init__(self, ptr):
|
||||
PassManager.__init__(self, ptr)
|
||||
|
||||
def __del__(self):
|
||||
PassManager.__del__(self)
|
||||
|
||||
def initialize(self):
|
||||
_core.LLVMInitializeFunctionPassManager(self.ptr)
|
||||
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -68,7 +68,7 @@ def call_setup(llvm_config):
|
|||
description='Python Bindings for LLVM',
|
||||
author='Mahadevan R',
|
||||
author_email='mdevan.foobar@gmail.com',
|
||||
url='http://code.google.com/p/llvm-py/',
|
||||
url='http://mdevan.nfshost.com/llvm-py/',
|
||||
packages=['llvm'],
|
||||
py_modules = [ 'llvm.core' ],
|
||||
ext_modules = [ ext_core ],)
|
||||
|
|
|
|||
381
test/testall.py
Normal file
381
test/testall.py
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# This script attempts to achieve 100% function and branch coverage for
|
||||
# all APIs in the llvm package. It only exercises the APIs, doesn't test
|
||||
# them for correctness.
|
||||
#
|
||||
|
||||
from llvm import *
|
||||
from llvm.core import *
|
||||
|
||||
ti = Type.int()
|
||||
|
||||
def do_module():
|
||||
print " Testing class Module"
|
||||
m = Module.new('test')
|
||||
m.target = 'a'
|
||||
a = m.target
|
||||
m.data_layout = 'a'
|
||||
a = m.data_layout
|
||||
m.add_type_name('a', ti)
|
||||
m.delete_type_name('a')
|
||||
s = str(m)
|
||||
s = m == Module.new('a')
|
||||
m.add_global_variable(ti, 'b')
|
||||
m.get_global_variable_named('b')
|
||||
gvs = list(m.global_variables)
|
||||
ft = Type.function(ti, [ti])
|
||||
m.add_function(ft, "func")
|
||||
m.get_function_named("func")
|
||||
fns = list(m.functions)
|
||||
try:
|
||||
m.verify()
|
||||
except LLVMException:
|
||||
pass
|
||||
|
||||
|
||||
def do_type():
|
||||
print " Testing class Type"
|
||||
for i in range(1,100):
|
||||
Type.int(i)
|
||||
Type.float()
|
||||
Type.double()
|
||||
Type.x86_fp80()
|
||||
Type.fp128()
|
||||
Type.ppc_fp128()
|
||||
Type.function(ti, [ti]*100, True)
|
||||
Type.function(ti, [ti]*100, False)
|
||||
Type.struct([ti]*100)
|
||||
Type.packed_struct([ti]*100)
|
||||
Type.array(ti, 100)
|
||||
Type.pointer(ti, 4)
|
||||
Type.vector(ti, 100)
|
||||
Type.void()
|
||||
Type.label()
|
||||
Type.opaque()
|
||||
s = str(ti)
|
||||
s = ti == Type.float()
|
||||
Type.opaque().refine(Type.int())
|
||||
s = ti.width
|
||||
ft = Type.function(ti, [ti]*10)
|
||||
ft.return_type
|
||||
ft.vararg
|
||||
s = list(ft.args)
|
||||
ft.arg_count
|
||||
st = Type.struct([ti]*10)
|
||||
s = st.element_count
|
||||
s = list(st.elements)
|
||||
s = st.packed
|
||||
st = Type.packed_struct([ti]*10)
|
||||
s = st.element_count
|
||||
s = list(st.elements)
|
||||
s = st.packed
|
||||
at = Type.array(ti, 100)
|
||||
s = at.element
|
||||
s = at.count
|
||||
pt = Type.pointer(ti, 10)
|
||||
pt.address_space
|
||||
vt = Type.vector(ti, 100)
|
||||
s = vt.element
|
||||
s = vt.count
|
||||
|
||||
|
||||
def do_typehandle():
|
||||
print " Testing class TypeHandle"
|
||||
th = TypeHandle.new(Type.opaque())
|
||||
ts = Type.struct([ Type.int(), Type.pointer(th.type) ])
|
||||
th.type.refine(ts)
|
||||
|
||||
|
||||
def do_value():
|
||||
print " Testing class Value"
|
||||
k = Constant.int(ti, 42)
|
||||
k.name = 'a'
|
||||
s = k.name
|
||||
t = s.type
|
||||
s = str(k)
|
||||
s = k == Constant.int(ti, 43)
|
||||
|
||||
|
||||
def do_constant():
|
||||
print " Testing class Constant"
|
||||
Constant.null(ti)
|
||||
Constant.all_ones(ti)
|
||||
Constant.undef(ti)
|
||||
Constant.int(ti, 10)
|
||||
Constant.int_signextend(ti, 10)
|
||||
Constant.real(Type.float(), "10.0")
|
||||
Constant.real(Type.float(), 3.14)
|
||||
Constant.string("test")
|
||||
Constant.stringz("test2")
|
||||
Constant.array(ti, [Constant.int(ti,42)]*10)
|
||||
Constant.struct([Constant.int(ti,42)]*10)
|
||||
Constant.packed_struct([Constant.int(ti,42)]*10)
|
||||
Constant.vector([Constant.int(ti,42)]*10)
|
||||
Constant.sizeof(ti)
|
||||
k = Constant.int(ti, 10)
|
||||
f = Constant.real(Type.float(), 3.1415)
|
||||
k.neg().not_().add(k).sub(k).mul(k).udiv(k).sdiv(k).urem(k)
|
||||
k.srem(k).and_(k).or_(k).icmp(IPRED_ULT, k)
|
||||
f.fdiv(f).frem(f).fcmp(RPRED_ULT, f)
|
||||
vi = Constant.vector([Constant.int(ti,42)]*10)
|
||||
vi.vicmp(IPRED_ULT, vi)
|
||||
vf = Constant.vector([Constant.real(Type.float(), 3.14)]*10)
|
||||
vf.vfcmp(RPRED_ULT, vf)
|
||||
k.shl(k).lshr(k).ashr(k)
|
||||
# TODO gep
|
||||
k.trunc(Type.int(1))
|
||||
k.sext(Type.int(64))
|
||||
k.zext(Type.int(64))
|
||||
Constant.real(Type.double(), 1.0).fptrunc(Type.float())
|
||||
Constant.real(Type.float(), 1.0).fpext(Type.double())
|
||||
k.uitofp(Type.float())
|
||||
k.sitofp(Type.float())
|
||||
f.fptoui(ti)
|
||||
f.fptosi(ti)
|
||||
p = Type.pointer(ti)
|
||||
# TODO ptrtoint
|
||||
k.inttoptr(p)
|
||||
f.bitcast(Type.int(32))
|
||||
k.trunc(Type.int(1)).select(k, k)
|
||||
vi.extract_element( Constant.int(ti,0) )
|
||||
vi.insert_element( k, k )
|
||||
vi.shuffle_vector( vi, vi )
|
||||
|
||||
|
||||
def do_global_value():
|
||||
print " Testing class GlobalValue"
|
||||
m = Module.new('a')
|
||||
gv = GlobalVariable.new(m, Type.int(), 'b')
|
||||
s = gv.is_declaration
|
||||
m = gv.module
|
||||
s = gv.is_declaration
|
||||
gv.linkage = LINKAGE_EXTERNAL
|
||||
s = gv.linkage
|
||||
gv.section = '.text'
|
||||
s = gv.section
|
||||
gv.visibility = VISIBILITY_HIDDEN
|
||||
s = gv.visibility
|
||||
gv.alignment = 8
|
||||
s = gv.alignment
|
||||
|
||||
|
||||
def do_global_variable():
|
||||
print " Testing class GlobalVariable"
|
||||
m = Module.new('a')
|
||||
gv = GlobalVariable.new(m, Type.int(), 'b')
|
||||
gv = GlobalVariable.get(m, 'b')
|
||||
gv.delete()
|
||||
gv = GlobalVariable.new(m, Type.int(), 'c')
|
||||
gv.initializer = Constant.int( ti, 10 )
|
||||
s = gv.initializer
|
||||
gv.global_constant = True
|
||||
s = gv.global_constant
|
||||
|
||||
|
||||
def do_argument():
|
||||
print " Testing class Argument"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti])
|
||||
f = Function.new(m, ft, 'func')
|
||||
a = f.args[0]
|
||||
a.add_attribute(ATTR_ZEXT)
|
||||
a.remove_attribute(ATTR_ZEXT)
|
||||
a.set_alignment(4)
|
||||
|
||||
|
||||
def do_function():
|
||||
print " Testing class Function"
|
||||
ft = Type.function(ti, [ti]*20)
|
||||
zz = Function.new(Module.new('z'), ft, 'foobar')
|
||||
del zz
|
||||
Function.new(Module.new('zz'), ft, 'foobar')
|
||||
m = Module.new('a')
|
||||
f = Function.new(m, ft, 'func')
|
||||
f.delete()
|
||||
ft = Type.function(ti, [ti]*20)
|
||||
f = Function.new(m, ft, 'func2')
|
||||
g = f.intrinsic_id
|
||||
f.calling_convenion = CC_FASTCALL
|
||||
g = f.calling_convenion
|
||||
f.collector = 'a'
|
||||
c = f.collector
|
||||
a = list(f.args)
|
||||
g = f.basic_block_count
|
||||
g = f.get_entry_basic_block()
|
||||
g = f.append_basic_block('a')
|
||||
g = f.get_entry_basic_block()
|
||||
g = list(f.basic_blocks)
|
||||
# LLVM misbehaves:
|
||||
#try:
|
||||
# f.verify()
|
||||
#except LLVMException:
|
||||
# pass
|
||||
|
||||
|
||||
def do_instruction():
|
||||
print " Testing class Instruction"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti]*20)
|
||||
f = Function.new(m, ft, 'func')
|
||||
b = f.append_basic_block('a')
|
||||
bb = Builder.new(b)
|
||||
i = bb.ret_void()
|
||||
bb2 = i.basic_block
|
||||
|
||||
|
||||
def do_callorinvokeinstruction():
|
||||
print " Testing class CallOrInvokeInstruction"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti])
|
||||
f = Function.new(m, ft, 'func')
|
||||
b = f.append_basic_block('a')
|
||||
bb = Builder.new(b)
|
||||
i = bb.invoke(f, [Constant.int(ti, 10)], b, b)
|
||||
a = i.calling_convention
|
||||
i.calling_convention = CC_FASTCALL
|
||||
i.add_parameter_attribute(0, ATTR_SEXT)
|
||||
i.remove_parameter_attribute(0, ATTR_SEXT)
|
||||
i.set_parameter_alignment(0, 8)
|
||||
|
||||
|
||||
def do_phinode():
|
||||
print " Testing class PhiNode"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti])
|
||||
f = Function.new(m, ft, 'func')
|
||||
b = f.append_basic_block('b')
|
||||
c = f.append_basic_block('c')
|
||||
d = f.append_basic_block('d')
|
||||
bb = Builder.new(d)
|
||||
p = bb.phi(ti)
|
||||
v = p.incoming_count
|
||||
p.add_incoming( Constant.int(ti, 10), b )
|
||||
p.add_incoming( Constant.int(ti, 10), c )
|
||||
p.get_incoming_value(0)
|
||||
p.get_incoming_block(0)
|
||||
|
||||
|
||||
def do_switchinstruction():
|
||||
print " Testing class SwitchInstruction"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti])
|
||||
f = Function.new(m, ft, 'func')
|
||||
b = f.append_basic_block('b')
|
||||
bb = Builder.new(b)
|
||||
s = bb.switch(f.args[0], b)
|
||||
s.add_case(Constant.int(ti, 10), b)
|
||||
|
||||
|
||||
def do_builder():
|
||||
print " Testing class Builder"
|
||||
m = Module.new('a')
|
||||
ft = Type.function(ti, [ti])
|
||||
f = Function.new(m, ft, 'func')
|
||||
blk = f.append_basic_block('b')
|
||||
b = Builder.new(blk)
|
||||
b.ret(Constant.int(ti, 10))
|
||||
b.position_at_beginning(blk)
|
||||
b.position_at_end(blk)
|
||||
b.position_before(blk.instructions[0])
|
||||
blk2 = b.block
|
||||
b.ret_void()
|
||||
b.ret(Constant.int(ti, 10))
|
||||
b.ret_many([Constant.int(ti, 10)]*10)
|
||||
b.branch(blk)
|
||||
b.cbranch(Constant.int(Type.int(1), 1), blk, blk)
|
||||
b.switch(f.args[0], blk)
|
||||
b.invoke(f, [Constant.int(ti,10)], blk, blk)
|
||||
b.unwind()
|
||||
b.unreachable()
|
||||
v = f.args[0]
|
||||
fv = Constant.real(Type.float(), "1.0")
|
||||
k = Constant.int(ti, 10)
|
||||
b.add(v, v)
|
||||
b.sub(v, v)
|
||||
b.mul(v, v)
|
||||
b.udiv(v, v)
|
||||
b.sdiv(v, v)
|
||||
b.fdiv(fv, fv)
|
||||
b.urem(v, v)
|
||||
b.srem(v, v)
|
||||
b.frem(fv, fv)
|
||||
b.shl(v, k)
|
||||
b.lshr(v, k)
|
||||
b.ashr(v, k)
|
||||
b.and_(v, v)
|
||||
b.or_(v, v)
|
||||
b.xor(v, v)
|
||||
b.neg(v)
|
||||
b.not_(v)
|
||||
p = b.malloc(Type.int())
|
||||
b.malloc_array(Type.int(), k)
|
||||
b.alloca(Type.int())
|
||||
b.alloca_array(Type.int(), k)
|
||||
b.free(p)
|
||||
b.load(p)
|
||||
b.store(k, p)
|
||||
# TODO gep
|
||||
b.trunc(v, Type.int(1))
|
||||
b.zext(v, Type.int(64))
|
||||
b.sext(v, Type.int(64))
|
||||
b.fptoui(fv, ti)
|
||||
b.fptosi(fv, ti)
|
||||
b.uitofp(k, Type.float())
|
||||
b.sitofp(k, Type.float())
|
||||
b.fptrunc(Constant.real(Type.double(), "1.0"), Type.float())
|
||||
b.fpext(Constant.real(Type.float(), "1.0"), Type.double())
|
||||
b.ptrtoint(p, ti)
|
||||
b.inttoptr(k, Type.pointer(Type.int()))
|
||||
b.bitcast(v, Type.float())
|
||||
b.icmp(IPRED_ULT, v, v)
|
||||
b.fcmp(RPRED_ULT, fv, fv)
|
||||
vi = Constant.vector([Constant.int(ti,42)]*10)
|
||||
b.vicmp(IPRED_ULT, vi, vi)
|
||||
vf = Constant.vector([Constant.real(Type.float(), 3.14)]*10)
|
||||
b.vfcmp(RPRED_ULT, vf, vf)
|
||||
# TODO b.getresult(v, 0)
|
||||
b.call(f, [v])
|
||||
b.select(Constant.int(Type.int(1), 1), blk, blk)
|
||||
b.vaarg(v, Type.int())
|
||||
b.extract_element(vi, v)
|
||||
b.insert_element(vi, v, v)
|
||||
b.shuffle_vector(vi, vi, vi)
|
||||
# NOTE: phi nodes without incoming values segfaults in LLVM during
|
||||
# destruction.
|
||||
i = b.phi(Type.int())
|
||||
i.add_incoming(v, blk)
|
||||
|
||||
|
||||
def do_moduleprovider():
|
||||
print " Testing class ModuleProvider"
|
||||
m = Module.new('a')
|
||||
mp = ModuleProvider.new(m)
|
||||
|
||||
|
||||
def do_llvm_core():
|
||||
print " Testing module llvm.core"
|
||||
do_module()
|
||||
do_type()
|
||||
do_typehandle()
|
||||
do_constant()
|
||||
do_global_value()
|
||||
do_global_variable()
|
||||
do_argument()
|
||||
do_function()
|
||||
do_instruction()
|
||||
do_callorinvokeinstruction()
|
||||
do_phinode()
|
||||
do_switchinstruction()
|
||||
do_builder()
|
||||
do_moduleprovider()
|
||||
|
||||
|
||||
def do_llvm():
|
||||
print "Testing package llvm"
|
||||
do_llvm_core()
|
||||
|
||||
|
||||
do_llvm()
|
||||
|
||||
|
|
@ -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' ]
|
||||
SKIP_FILES = [ 'layout.conf', '.svn', 'instrset.inc' ]
|
||||
|
||||
# asciidoc command line
|
||||
ASCIIDOC = 'asciidoc --unsafe --conf-file=${srcdir}/layout.conf -a icons -o ${outfile} ${infile}'
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ Browse SVN, http://code.google.com/p/llvm-py/source/browse/[http://code.google.c
|
|||
Issues tracker, http://code.google.com/p/llvm-py/issues/list[http://code.google.com/p/llvm-py/issues/list]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
SVN HEAD can be checked out like so:
|
||||
|
||||
----
|
||||
|
|
@ -21,3 +20,12 @@ $ svn checkout http://llvm-py.googlecode.com/svn/trunk/ llvm-py
|
|||
Mahadevan R (mdevan.foobar@gmail.com) is available to answer your
|
||||
queries.
|
||||
|
||||
Current Next Steps
|
||||
------------------
|
||||
|
||||
- Wrap GenericValue, function call args for execution engine.
|
||||
- Add APIs to read/write `.bc` and `.ll` files.
|
||||
- Wrap `lto`.
|
||||
- Add examples.
|
||||
- Update documentation.
|
||||
- Improve tests.
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ http://llvm.org/[LLVM]. It's goal is to expose enough of LLVM APIs to
|
|||
implement a compiler or VM in pure Python. Currently, llvm-py is
|
||||
available for LLVM 2.3 and Python 2.5, on Linux/x86. It is expected to
|
||||
be usable on various unices, as well as with Python 2.4, with minimal
|
||||
changes, if any. It should be stable enough for you to play with.
|
||||
changes, if any.
|
||||
|
||||
llvm-py is just hatching, and your contributions would be most welcome.
|
||||
llvm-py is just hatching. It should be stable enough to start hacking
|
||||
away, though. Be sure to send in a patch (or shout at the author) if you
|
||||
miss any specific LLVM API.
|
||||
|
||||
News
|
||||
----
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
llvm-py User Guide
|
||||
===================
|
||||
|
||||
NOTE: This document is updated constantly. Check back often.
|
||||
|
||||
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.
|
||||
|
|
@ -46,7 +48,7 @@ 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:
|
||||
|
||||
- compilers, both gcc and g++
|
||||
- C and C\+\+ compilers (gcc/g\+\+)
|
||||
- Python itself
|
||||
- Python development files (headers and libraries)
|
||||
- LLVM, either installed or built
|
||||
|
|
@ -56,7 +58,11 @@ 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.
|
||||
|
||||
Tip: If LLVM 2.3 does not install cleanly, try installing 'ocamldoc'
|
||||
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.
|
||||
|
||||
|
||||
|
|
@ -108,11 +114,16 @@ libraries of LLVM, use this:
|
|||
$ tar jxvf llvm-py-0.2.tar.bz2
|
||||
$ cd llvm-py-0.2
|
||||
$ python setup.py build -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
|
||||
$ sudo python setup.py install -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 (65MB+) !
|
||||
|
||||
`setup.py` is a standard Python distutils script. See the Python
|
||||
documentation regarding http://docs.python.org/inst/inst.html[Installing
|
||||
Python Modules] and http://docs.python.org/dist/dist.html[Distributing
|
||||
Python Modules] for more information on such scripts.
|
||||
|
||||
|
||||
[[uninstall]]
|
||||
Uninstall
|
||||
|
|
@ -891,6 +902,12 @@ r3 = Constant.undef() # an `undefined' value
|
|||
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
TypeHandle (llvm.core)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
Instructions (llvm.core)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -81,10 +81,45 @@ cellspacing="0" cellpadding="4">
|
|||
queries.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Current Next Steps</h2>
|
||||
<div class="sectionbody">
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
Wrap GenericValue, function call args for execution engine.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Add APIs to read/write <tt>.bc</tt> and <tt>.ll</tt> files.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Wrap <tt>lto</tt>.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Add examples.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Update documentation.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Improve tests.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Web pages © Mahadevan R. Generated with <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.
|
||||
Last updated 10-Jun-2008.
|
||||
Last updated 15-Jun-2008.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@
|
|||
implement a compiler or VM in pure Python. Currently, llvm-py is
|
||||
available for LLVM 2.3 and Python 2.5, on Linux/x86. It is expected to
|
||||
be usable on various unices, as well as with Python 2.4, with minimal
|
||||
changes, if any. It should be stable enough for you to play with.</p>
|
||||
<p>llvm-py is just hatching, and your contributions would be most welcome.</p>
|
||||
changes, if any.</p>
|
||||
<p>llvm-py is just hatching. It should be stable enough to start hacking
|
||||
away, though. Be sure to send in a patch (or shout at the author) if you
|
||||
miss any specific LLVM API.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h2>News</h2>
|
||||
|
|
@ -60,7 +62,7 @@ changes, if any. It should be stable enough for you to play with.</p>
|
|||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Web pages © Mahadevan R. Generated with <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.
|
||||
Last updated 10-Jun-2008.
|
||||
Last updated 15-Jun-2008.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,14 @@
|
|||
</div>
|
||||
<div id="preamble">
|
||||
<div class="sectionbody">
|
||||
<div class="admonitionblock">
|
||||
<table><tr>
|
||||
<td class="icon">
|
||||
<img src="./images/icons/note.png" alt="Note" />
|
||||
</td>
|
||||
<td class="content">This document is updated constantly. Check back often.</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
<p>llvm-py provides Python bindings for LLVM. This document explains how
|
||||
you can setup and use it. A working knowledge of Python and a basic idea
|
||||
of LLVM is assumed.</p>
|
||||
|
|
@ -73,7 +81,7 @@ required for this:</p>
|
|||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
compilers, both gcc and g++
|
||||
C and C++ compilers (gcc/g++)
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
|
|
@ -96,7 +104,10 @@ LLVM, either installed or built
|
|||
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.</p>
|
||||
<p>Tip: If LLVM 2.3 does not install cleanly, try installing <em>ocamldoc</em>
|
||||
<p>It does not matter which compiler LLVM itself was built with (g++,
|
||||
llvm-g++ or any other); llvm-py can be built with any compiler. It has
|
||||
been tried only with gcc/g++ though.</p>
|
||||
<p>Tip: If LLVM 2.3 does not install cleanly, try installing “ocamldoc”
|
||||
first.</p>
|
||||
<h3>llvm-config</h3>
|
||||
<p>Inorder to build llvm-py, it's build script needs to know from where to
|
||||
|
|
@ -136,9 +147,13 @@ libraries of LLVM, use this:</p>
|
|||
<pre><tt>$ tar jxvf llvm-py-0.2.tar.bz2
|
||||
$ cd llvm-py-0.2
|
||||
$ python setup.py build -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
|
||||
$ sudo python setup.py install -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config</tt></pre>
|
||||
$ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config</tt></pre>
|
||||
</div></div>
|
||||
<p>Be warned that debug binaries will be huge (65MB+) !</p>
|
||||
<p><tt>setup.py</tt> is a standard Python distutils script. See the Python
|
||||
documentation regarding <a href="http://docs.python.org/inst/inst.html">Installing
|
||||
Python Modules</a> and <a href="http://docs.python.org/dist/dist.html">Distributing
|
||||
Python Modules</a> for more information on such scripts.</p>
|
||||
<h3><a id="uninstall"></a>Uninstall</h3>
|
||||
<p>To get rid of llvm-py completely, if you wish to do so:</p>
|
||||
<div class="listingblock">
|
||||
|
|
@ -1659,6 +1674,8 @@ r2 <span style="color: #990000">=</span> <span style="color: #009900">Constant</
|
|||
|
||||
r3 <span style="color: #990000">=</span> <span style="color: #009900">Constant</span><span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">undef</span></span><span style="color: #990000">()</span> <span style="font-style: italic"><span style="color: #9A1900"># an `undefined' value</span></span>
|
||||
</tt></pre></div></div>
|
||||
<h3>TypeHandle (llvm.core)</h3>
|
||||
<p>TODO</p>
|
||||
<h3>Instructions (llvm.core)</h3>
|
||||
<p>TODO</p>
|
||||
<h3>Basic Block (llvm.core)</h3>
|
||||
|
|
@ -1702,7 +1719,7 @@ reached at <em>mdevan.foobar@gmail.com</em>.</p>
|
|||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Web pages © Mahadevan R. Generated with <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.
|
||||
Last updated 12-Jun-2008.
|
||||
Last updated 15-Jun-2008.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue