Execution engine and passes work. Documentation and tests updated.

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@4 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2008-06-07 13:44:25 +00:00
commit 2255a7e5dd
15 changed files with 559 additions and 396 deletions

View file

@ -12,3 +12,28 @@ class LLVMException(Exception):
Exception.__init__(self, msg) Exception.__init__(self, msg)
#===----------------------------------------------------------------------===
# Ownables
#===----------------------------------------------------------------------===
class Ownable(object):
def __init__(self, ptr, del_fn):
self.ptr = ptr
self.owner = None
self.del_fn = del_fn
def _own(self, owner):
if self.owner:
raise LLVMException, "object already owned"
self.owner = owner
def _disown(self):
if not self.owner:
raise LLVMException, "not owned"
self.owner = None
def __del__(self):
if not self.owner:
self.del_fn(self.ptr)

View file

@ -6,6 +6,7 @@
/* LLVM includes */ /* LLVM includes */
#include "llvm-c/Analysis.h" #include "llvm-c/Analysis.h"
#include "llvm-c/Transforms/Scalar.h" #include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/ExecutionEngine.h"
/* libc includes */ /* libc includes */
#include <stdarg.h> /* for malloc(), free() */ #include <stdarg.h> /* for malloc(), free() */
@ -617,6 +618,97 @@ _wrap_obj2none(LLVMAddGVNPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddCFGSimplificationPass, LLVMPassManagerRef) _wrap_obj2none(LLVMAddCFGSimplificationPass, LLVMPassManagerRef)
/*===----------------------------------------------------------------------===*/
/* Target Data */
/*===----------------------------------------------------------------------===*/
_wrap_str2obj(LLVMCreateTargetData, LLVMTargetDataRef)
_wrap_obj2none(LLVMDisposeTargetData, LLVMTargetDataRef)
static PyObject *
_wLLVMTargetDataAsString(PyObject *self, PyObject *args)
{
PyObject *obj;
LLVMTargetDataRef td;
char *tdrep = 0;
PyObject *ret;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
td = (LLVMTargetDataRef) PyCObject_AsVoidPtr(obj);
tdrep = LLVMCopyStringRepOfTargetData(td);
ret = PyString_FromString(tdrep);
LLVMDisposeMessage(tdrep);
return ret;
}
_wrap_objobj2none(LLVMAddTargetData, LLVMTargetDataRef, LLVMPassManagerRef)
/*===----------------------------------------------------------------------===*/
/* Execution Engine */
/*===----------------------------------------------------------------------===*/
static PyObject *
_wLLVMCreateExecutionEngine(PyObject *self, PyObject *args)
{
LLVMModuleProviderRef mp;
PyObject *obj;
int force_interpreter;
LLVMExecutionEngineRef ee;
char *outmsg;
PyObject *ret;
int error;
if (!PyArg_ParseTuple(args, "Oi", &obj, &force_interpreter))
return NULL;
mp = (LLVMModuleProviderRef) PyCObject_AsVoidPtr(obj);
if (force_interpreter)
error = LLVMCreateInterpreter(&ee, mp, &outmsg);
else
error = LLVMCreateJITCompiler(&ee, mp, &outmsg);
if (error) {
ret = PyString_FromString(outmsg);
LLVMDisposeMessage(outmsg);
} else {
ret = ctor_LLVMExecutionEngineRef(ee);
}
return ret;
}
_wrap_obj2none(LLVMDisposeExecutionEngine, LLVMExecutionEngineRef)
static PyObject *
_wLLVMRunFunction(PyObject *self, PyObject *args)
{
PyObject *obj1, *obj2, *obj3;
LLVMExecutionEngineRef ee;
LLVMValueRef fn;
if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3))
return NULL;
/* obj3 is a list of args to the function, ignored currently */
ee = (LLVMExecutionEngineRef) PyCObject_AsVoidPtr(obj1);
fn = (LLVMValueRef) PyCObject_AsVoidPtr(obj2);
LLVMRunFunction(ee, fn, 0, NULL);
/* fn return value ignore currently */
Py_RETURN_NONE;
}
_wrap_obj2obj(LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef,
LLVMTargetDataRef)
/*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
/* Python member method table */ /* Python member method table */
/*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
@ -948,6 +1040,18 @@ static PyMethodDef core_methods[] = {
_method( LLVMAddGVNPass ) _method( LLVMAddGVNPass )
_method( LLVMAddCFGSimplificationPass ) _method( LLVMAddCFGSimplificationPass )
/* Target Data */
_method( LLVMCreateTargetData )
_method( LLVMDisposeTargetData )
_method( LLVMTargetDataAsString )
_method( LLVMAddTargetData )
/* Execution Engine */
_method( LLVMCreateExecutionEngine )
_method( LLVMDisposeExecutionEngine )
_method( LLVMRunFunction )
_method( LLVMGetExecutionEngineTargetData )
{ NULL } { NULL }
}; };

View file

@ -1,12 +1,19 @@
"""Utility functions and classes. """Utility functions and classes.
Not for public use!""" Used only in other modules, not for public use."""
import core import core
import llvm
#===----------------------------------------------------------------------===
# A set of helpers to check various things. Raises exceptions on
# failures.
#===----------------------------------------------------------------------===
def _check_gen(obj, type): def _check_gen(obj, type):
if not isinstance(obj, type): if not isinstance(obj, type):
msg = "argument must be an instance of llvm.core.%s (or of a class derived from it)" % type_str msg = "argument not an instance of llvm.core.%s" % type_str
raise TypeError, msg raise TypeError, msg
def check_is_type(obj): _check_gen(obj, core.Type) def check_is_type(obj): _check_gen(obj, core.Type)
@ -15,25 +22,54 @@ def check_is_pointer(obj): _check_gen(obj, core.Pointer)
def check_is_constant(obj): _check_gen(obj, core.Constant) def check_is_constant(obj): _check_gen(obj, core.Constant)
def check_is_function(obj): _check_gen(obj, core.Function) def check_is_function(obj): _check_gen(obj, core.Function)
def check_is_basic_block(obj): _check_gen(obj, core.BasicBlock) def check_is_basic_block(obj): _check_gen(obj, core.BasicBlock)
def check_is_module(obj): _check_gen(obj, core.Module)
def check_is_module_provider(obj): _check_gen(obj, core.ModuleProvider) def check_is_module_provider(obj): _check_gen(obj, core.ModuleProvider)
def unpack_gen(objlist, check_fn): def check_is_unowned(ownable):
if ownable.owner:
raise llvm.LLVMException, "object is already owned"
#===----------------------------------------------------------------------===
# A set of helpers to unpack a list of Python wrapper objects
# into a list of PyCObject wrapped objects, checking types along
# the way.
#===----------------------------------------------------------------------===
def _unpack_gen(objlist, check_fn):
for obj in objlist: check_fn(obj) for obj in objlist: check_fn(obj)
return [ obj.ptr for obj in objlist ] return [ obj.ptr for obj in objlist ]
def unpack_types(objlist): return unpack_gen(objlist, check_is_type) def unpack_types(objlist): return _unpack_gen(objlist, check_is_type)
def unpack_values(objlist): return unpack_gen(objlist, check_is_value) def unpack_values(objlist): return _unpack_gen(objlist, check_is_value)
def unpack_constants(objlist): return unpack_gen(objlist, check_is_constant) def unpack_constants(objlist): return _unpack_gen(objlist, check_is_constant)
#===----------------------------------------------------------------------===
# Helper to wrap over iterables (LLVMFirstXXX, LLVMNextXXX). This used
# to be a generator, but that loses subscriptability of the result, so
# we now return a list.
#===----------------------------------------------------------------------===
def wrapiter(first, next, container, wrapper): def wrapiter(first, next, container, wrapper):
# ptr = first(container)
# while ptr:
# yield wrapper(ptr)
# ptr = next(ptr)
ret = []
ptr = first(container) ptr = first(container)
while ptr: while ptr:
yield wrapper(ptr) ret.append(wrapper(ptr))
ptr = next(ptr) ptr = next(ptr)
return ret
#===----------------------------------------------------------------------===
# Dummy owner, will not delete ownee. Be careful.
#===----------------------------------------------------------------------===
class dummy_owner(object): class dummy_owner(object):
def __init__(self, ownee): def __init__(self, ownee):
ownee._own(self) ownee._own(self)

View file

@ -6,6 +6,7 @@ in-memory intermediate representation (IR) data structures."""
import llvm # top-level, for common stuff import llvm # top-level, for common stuff
import _core # C wrappers import _core # C wrappers
from _util import * # utility functions
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
@ -96,51 +97,12 @@ ATTR_READ_NONE = 512
ATTR_READONLY = 1024 ATTR_READONLY = 1024
#===----------------------------------------------------------------------===
# Helper functions
#===----------------------------------------------------------------------===
def _check_gen(obj, type, type_str):
if not isinstance(obj, type):
type_str = type.__module__ + "." + type.__name__
msg = "argument must be an instance of llvm.core.%s (or of a class derived from it)" % type_str
raise TypeError, msg
def _check_is_type(obj): _check_gen(obj, Type, "Type")
def _check_is_value(obj): _check_gen(obj, Value, "Value")
def _check_is_pointer(obj): _check_gen(obj, Pointer, "Pointer")
def _check_is_constant(obj): _check_gen(obj, Constant, "Constant")
def _check_is_function(obj): _check_gen(obj, Function, "Function")
def _check_is_basic_block(obj): _check_gen(obj, BasicBlock, "BasicBlock")
def _check_is_module_provider(obj): _check_gen(obj, ModuleProvider, "ModuleProvider")
def _unpack_gen(objlist, check_fn):
for obj in objlist: check_fn(obj)
return [ obj.ptr for obj in objlist ]
def _unpack_types(objlist): return _unpack_gen(objlist, _check_is_type)
def _unpack_values(objlist): return _unpack_gen(objlist, _check_is_value)
def _unpack_constants(objlist): return _unpack_gen(objlist, _check_is_constant)
def _wrapiter(first, next, container, wrapper):
ptr = first(container)
while ptr:
yield wrapper(ptr)
ptr = next(ptr)
class _dummy_owner(object):
def __init__(self, ownee):
ownee._own(self)
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
# Module # Module
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
class Module(object): class Module(llvm.Ownable):
"""A Module instance stores all the information related to an LLVM module. """A Module instance stores all the information related to an LLVM module.
Modules are the top level container of all other LLVM Intermediate Modules are the top level container of all other LLVM Intermediate
@ -168,12 +130,10 @@ class Module(object):
Use the static method `Module.new' instead. Use the static method `Module.new' instead.
""" """
self.ptr = ptr llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule)
self.owner = None
def __del__(self): def __del__(self):
if not self.owner: llvm.Ownable.__del__(self)
_core.LLVMDisposeModule(self.ptr)
def __str__(self): def __str__(self):
"""Text representation of a module. """Text representation of a module.
@ -192,10 +152,6 @@ class Module(object):
else: else:
return False return False
def _own(self, owner):
assert not self.owner
self.owner = owner
def _get_target(self): def _get_target(self):
return _core.LLVMGetTarget(self.ptr) return _core.LLVMGetTarget(self.ptr)
@ -227,7 +183,7 @@ class Module(object):
if entry already existed (in which case nothing is changed), if entry already existed (in which case nothing is changed),
False otherwise. False otherwise.
""" """
_check_is_type(ty) check_is_type(ty)
return _core.LLVMAddTypeName(self.ptr, name, ty.ptr) != 0 return _core.LLVMAddTypeName(self.ptr, name, ty.ptr) != 0
def delete_type_name(self, name): def delete_type_name(self, name):
@ -255,7 +211,7 @@ class Module(object):
# gv is an instance of GlobalVariable # gv is an instance of GlobalVariable
# do stuff with gv # do stuff with gv
""" """
return _wrapiter(_core.LLVMGetFirstGlobal, _core.LLVMGetNextGlobal, return wrapiter(_core.LLVMGetFirstGlobal, _core.LLVMGetNextGlobal,
self.ptr, GlobalVariable) self.ptr, GlobalVariable)
def add_function(self, ty, name): def add_function(self, ty, name):
@ -276,7 +232,7 @@ class Module(object):
# f is an instance of Function # f is an instance of Function
# do stuff with f # do stuff with f
""" """
return _wrapiter(_core.LLVMGetFirstFunction, return wrapiter(_core.LLVMGetFirstFunction,
_core.LLVMGetNextFunction, self.ptr, Function) _core.LLVMGetNextFunction, self.ptr, Function)
def verify(self): def verify(self):
@ -291,13 +247,19 @@ class Module(object):
class Type(object): class Type(object):
"""Represents a type, like a 32-bit integer or an 80-bit x86 float.
Use one of the static methods to create an instance. Example:
ty = Type.double()
"""
@staticmethod @staticmethod
def int(bits=32): def int(bits=32):
"""Create an integer type having the given bit width."""
if bits == 1: if bits == 1:
return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER) return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER)
elif bits == 8: elif bits == 8:
return _make_type(_core.LLVMInt2Type(), TYPE_INTEGER) return _make_type(_core.LLVMInt8Type(), TYPE_INTEGER)
elif bits == 16: elif bits == 16:
return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER) return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER)
elif bits == 32: elif bits == 32:
@ -309,54 +271,76 @@ class Type(object):
@staticmethod @staticmethod
def float(): def float():
"""Create a 32-bit floating point type."""
return _make_type(_core.LLVMFloatType(), TYPE_FLOAT) return _make_type(_core.LLVMFloatType(), TYPE_FLOAT)
@staticmethod @staticmethod
def double(): def double():
"""Create a 64-bit floating point type."""
return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE) return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE)
@staticmethod @staticmethod
def x86_fp80(): def x86_fp80():
"""Create a 80-bit x86 floating point type."""
return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80) return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80)
@staticmethod @staticmethod
def fp128(): def fp128():
"""Create a 128-bit floating point type (with 112-bit
mantissa)."""
return _make_type(_core.LLVMFP128Type(), TYPE_FP128) return _make_type(_core.LLVMFP128Type(), TYPE_FP128)
@staticmethod @staticmethod
def ppc_fp128(): def ppc_fp128():
"""Create a 128-bit floating point type (two 64-bits)."""
return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128) return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128)
@staticmethod @staticmethod
def function(return_ty, param_tys, var_arg=False): def function(return_ty, param_tys, var_arg=False):
_check_is_type(return_ty) """Create a function type.
Creates a function type that returns a value of type
`return_ty', takes arguments of types as given in the iterable
`param_tys'. Set `var_arg' to True (default is False) for a
variadic function."""
check_is_type(return_ty)
var_arg = 1 if var_arg else 0 # convert to int var_arg = 1 if var_arg else 0 # convert to int
params = _unpack_types(param_tys) 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 @staticmethod
def struct(element_tys): # not packed def struct(element_tys): # not packed
elems = _unpack_types(element_tys) """Create a (unpacked) structure type.
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 struct_packed() method."""
elems = unpack_types(element_tys)
return _make_type(_core.LLVMStructType(elems, 0), TYPE_STRUCT) return _make_type(_core.LLVMStructType(elems, 0), TYPE_STRUCT)
@staticmethod @staticmethod
def struct_packed(element_tys): def struct_packed(element_tys):
elems = _unpack_types(element_tys) """Create a (packed) structure type.
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."""
elems = unpack_types(element_tys)
return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT) return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT)
@staticmethod @staticmethod
def array(element_ty, count): def array(element_ty, count):
_check_is_type(element_ty) check_is_type(element_ty)
return _make_type(_core.LLVMArrayType(element_ty.ptr, count), TYPE_ARRAY) return _make_type(_core.LLVMArrayType(element_ty.ptr, count), TYPE_ARRAY)
@staticmethod @staticmethod
def pointer(pointee_ty, addr_space=0): def pointer(pointee_ty, addr_space=0):
_check_is_type(pointee_ty) check_is_type(pointee_ty)
return _make_type(_core.LLVMPointerType(pointee_ty.ptr, addr_space), TYPE_POINTER) return _make_type(_core.LLVMPointerType(pointee_ty.ptr, addr_space), TYPE_POINTER)
@staticmethod @staticmethod
def vector(element_ty, count): def vector(element_ty, count):
_check_is_type(element_ty) check_is_type(element_ty)
return _make_type(_core.LLVMVectorType(element_ty.ptr, count), TYPE_VECTOR) return _make_type(_core.LLVMVectorType(element_ty.ptr, count), TYPE_VECTOR)
@staticmethod @staticmethod
@ -390,7 +374,7 @@ class Type(object):
This object is no longer valid after refining, so do not hold references This object is no longer valid after refining, so do not hold references
to it after calling.""" to it after calling."""
_check_is_type(dest) check_is_type(dest)
_core.LLVMRefineType(self.ptr, dest.ptr) _core.LLVMRefineType(self.ptr, dest.ptr)
self.ptr = None self.ptr = None
@ -517,7 +501,7 @@ class TypeHandle(object):
@staticmethod @staticmethod
def new(abstract_ty): def new(abstract_ty):
_check_is_type(abstract_ty) check_is_type(abstract_ty)
return TypeHandle(_core.LLVMCreateTypeHandle(abstract_ty.ptr)) return TypeHandle(_core.LLVMCreateTypeHandle(abstract_ty.ptr))
def __init__(self, ptr): def __init__(self, ptr):
@ -570,32 +554,32 @@ class Constant(Value):
@staticmethod @staticmethod
def null(ty): def null(ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstNull(ty.ptr)); return Constant(_core.LLVMConstNull(ty.ptr));
@staticmethod @staticmethod
def all_ones(ty): def all_ones(ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstAllOnes(ty.ptr)); return Constant(_core.LLVMConstAllOnes(ty.ptr));
@staticmethod @staticmethod
def undef(ty): def undef(ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMGetUndef(ty.ptr)); return Constant(_core.LLVMGetUndef(ty.ptr));
@staticmethod @staticmethod
def int(ty, value): def int(ty, value):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstInt(ty.ptr, value, 0)) return Constant(_core.LLVMConstInt(ty.ptr, value, 0))
@staticmethod @staticmethod
def int_signextend(ty, value): def int_signextend(ty, value):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstInt(ty.ptr, value, 1)) return Constant(_core.LLVMConstInt(ty.ptr, value, 1))
@staticmethod @staticmethod
def real(ty, value): def real(ty, value):
_check_is_type(ty) check_is_type(ty)
if isinstance(value, str): if isinstance(value, str):
return Constant(_core.LLVMConstRealOfString(ty.ptr, value)) return Constant(_core.LLVMConstRealOfString(ty.ptr, value))
else: else:
@ -611,32 +595,32 @@ class Constant(Value):
@staticmethod @staticmethod
def array(ty, consts): def array(ty, consts):
_check_is_type(ty) check_is_type(ty)
const_ptrs = _unpack_constants(consts) const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstArray(ty.ptr, const_ptrs)) return Constant(_core.LLVMConstArray(ty.ptr, const_ptrs))
@staticmethod @staticmethod
def struct(consts): # not packed def struct(consts): # not packed
const_ptrs = _unpack_constants(consts) const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstStruct(consts, 0)) return Constant(_core.LLVMConstStruct(consts, 0))
@staticmethod @staticmethod
def struct_packed(consts): def struct_packed(consts):
const_ptrs = _unpack_constants(consts) const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstStruct(consts, 1)) return Constant(_core.LLVMConstStruct(consts, 1))
@staticmethod @staticmethod
def vector(consts): def vector(consts):
const_ptrs = _unpack_constants(consts) const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstVector(const_ptrs)) return Constant(_core.LLVMConstVector(const_ptrs))
@staticmethod @staticmethod
def sizeof(ty): def sizeof(ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMSizeOf(ty.ptr)) return Constant(_core.LLVMSizeOf(ty.ptr))
def __init__(self, ptr): def __init__(self, ptr):
self.ptr = ptr Value.__init__(self, ptr)
def neg(self): def neg(self):
return Constant(_core.LLVMConstNeg(self.ptr)) return Constant(_core.LLVMConstNeg(self.ptr))
@ -645,145 +629,145 @@ class Constant(Value):
return Constant(_core.LLVMConstNot(self.ptr)) return Constant(_core.LLVMConstNot(self.ptr))
def add(self, rhs): def add(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstAdd(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstAdd(self.ptr, rhs.ptr))
def sub(self, rhs): def sub(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstSub(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstSub(self.ptr, rhs.ptr))
def mul(self, rhs): def mul(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstMul(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstMul(self.ptr, rhs.ptr))
def udiv(self, rhs): def udiv(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstUDiv(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstUDiv(self.ptr, rhs.ptr))
def sdiv(self, rhs): def sdiv(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstSDiv(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstSDiv(self.ptr, rhs.ptr))
def fdiv(self, rhs): def fdiv(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstFDiv(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstFDiv(self.ptr, rhs.ptr))
def urem(self, rhs): def urem(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstURem(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstURem(self.ptr, rhs.ptr))
def srem(self, rhs): def srem(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstSRem(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstSRem(self.ptr, rhs.ptr))
def and_(self, rhs): def and_(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstAnd(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstAnd(self.ptr, rhs.ptr))
def or_(self, rhs): def or_(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstOr(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstOr(self.ptr, rhs.ptr))
def xor(self, rhs): def xor(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstXor(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstXor(self.ptr, rhs.ptr))
def icmp(self, int_pred, rhs): def icmp(self, int_pred, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstICmp(self.ptr, int_pred, rhs.ptr)) return Constant(_core.LLVMConstICmp(self.ptr, int_pred, rhs.ptr))
def fcmp(self, real_pred, rhs): def fcmp(self, real_pred, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstFCmp(self.ptr, real_pred, rhs.ptr)) return Constant(_core.LLVMConstFCmp(self.ptr, real_pred, rhs.ptr))
def shl(self, rhs): def shl(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstShl(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstShl(self.ptr, rhs.ptr))
def lshr(self, rhs): def lshr(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstLShr(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstLShr(self.ptr, rhs.ptr))
def ashr(self, rhs): def ashr(self, rhs):
_check_is_constant(rhs) check_is_constant(rhs)
return Constant(_core.LLVMConstAShr(self.ptr, rhs.ptr)) return Constant(_core.LLVMConstAShr(self.ptr, rhs.ptr))
def gep(self, indices): def gep(self, indices):
index_ptrs = _unpack_constants(indices) index_ptrs = unpack_constants(indices)
return Constant(_core.LLVMConstGEP(self.ptr, index_ptrs)) return Constant(_core.LLVMConstGEP(self.ptr, index_ptrs))
def trunc(self, ty): def trunc(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstTrunc(self.ptr, ty.ptr)) return Constant(_core.LLVMConstTrunc(self.ptr, ty.ptr))
def sext(self, ty): def sext(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstSExt(self.ptr, ty.ptr)) return Constant(_core.LLVMConstSExt(self.ptr, ty.ptr))
def zext(self, ty): def zext(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstZExt(self.ptr, ty.ptr)) return Constant(_core.LLVMConstZExt(self.ptr, ty.ptr))
def fptrunc(self, ty): def fptrunc(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstFPTrunc(self.ptr, ty.ptr)) return Constant(_core.LLVMConstFPTrunc(self.ptr, ty.ptr))
def fpext(self, ty): def fpext(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstFPExt(self.ptr, ty.ptr)) return Constant(_core.LLVMConstFPExt(self.ptr, ty.ptr))
def uitofp(self, ty): def uitofp(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstUIToFP(self.ptr, ty.ptr)) return Constant(_core.LLVMConstUIToFP(self.ptr, ty.ptr))
def sitofp(self, ty): def sitofp(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstSIToFP(self.ptr, ty.ptr)) return Constant(_core.LLVMConstSIToFP(self.ptr, ty.ptr))
def fptoui(self, ty): def fptoui(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstFPToUI(self.ptr, ty.ptr)) return Constant(_core.LLVMConstFPToUI(self.ptr, ty.ptr))
def fptosi(self, ty): def fptosi(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstFPToSI(self.ptr, ty.ptr)) return Constant(_core.LLVMConstFPToSI(self.ptr, ty.ptr))
def ptrtoint(self, ty): def ptrtoint(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstPtrToInt(self.ptr, ty.ptr)) return Constant(_core.LLVMConstPtrToInt(self.ptr, ty.ptr))
def inttoptr(self, ty): def inttoptr(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstIntToPtr(self.ptr, ty.ptr)) return Constant(_core.LLVMConstIntToPtr(self.ptr, ty.ptr))
def bitcast(self, ty): def bitcast(self, ty):
_check_is_type(ty) check_is_type(ty)
return Constant(_core.LLVMConstBitCast(self.ptr, ty.ptr)) return Constant(_core.LLVMConstBitCast(self.ptr, ty.ptr))
def select(self, true_const, false_const): def select(self, true_const, false_const):
_check_is_constant(true_const) check_is_constant(true_const)
_check_is_constant(false_const) check_is_constant(false_const)
return Constant(_core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr)) return Constant(_core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr))
def extract(self, index): # note: self must be a _vector_ constant def extract(self, index): # note: self must be a _vector_ constant
_check_is_constant(index) check_is_constant(index)
return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr)) return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr))
def insert(self, value, index): # note: self must be a _vector_ constant def insert(self, value, index): # note: self must be a _vector_ constant
_check_is_constant(value) check_is_constant(value)
_check_is_constant(index) check_is_constant(index)
return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr)) return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr))
def shuffle(self, vector_b, mask): # note: self must be a _vector_ constant def shuffle(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(vector_b) # note: vector_b must be a _vector_ constant
_check_is_constant(mask) check_is_constant(mask)
return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr)) return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr))
class GlobalValue(Value): class GlobalValue(Constant):
def __init__(self, ptr): def __init__(self, ptr):
self.ptr = ptr Constant.__init__(self, ptr)
def get_linkage(self): return _core.LLVMGetLinkage(self.ptr) def get_linkage(self): return _core.LLVMGetLinkage(self.ptr)
def set_linkage(self, value): _core.LLVMSetLinkage(self.ptr, value) def set_linkage(self, value): _core.LLVMSetLinkage(self.ptr, value)
@ -808,7 +792,7 @@ class GlobalValue(Value):
@property @property
def module(self): def module(self):
mod = Module(_core.LLVMGetGlobalParent(self.ptr)) mod = Module(_core.LLVMGetGlobalParent(self.ptr))
owner = _dummy_owner(mod) owner = dummy_owner(mod)
return mod return mod
@ -816,7 +800,7 @@ class GlobalVariable(GlobalValue):
@staticmethod @staticmethod
def new(module, ty, name): def new(module, ty, name):
_check_is_type(ty) check_is_type(ty)
return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name)) return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name))
@staticmethod @staticmethod
@ -837,7 +821,7 @@ class GlobalVariable(GlobalValue):
return None return None
def set_initializer(self, const): def set_initializer(self, const):
_check_is_constant(const) check_is_constant(const)
_core.LLVMSetInitializer(self.ptr, const.ptr) _core.LLVMSetInitializer(self.ptr, const.ptr)
initializer = property(get_initializer, set_initializer) initializer = property(get_initializer, set_initializer)
@ -902,7 +886,7 @@ class Function(GlobalValue):
@property @property
def args(self): def args(self):
return _wrapiter(_core.LLVMGetFirstParam, _core.LLVMGetNextParam, return wrapiter(_core.LLVMGetFirstParam, _core.LLVMGetNextParam,
self.ptr, Argument) self.ptr, Argument)
@property @property
@ -917,7 +901,7 @@ class Function(GlobalValue):
@property @property
def basic_blocks(self): def basic_blocks(self):
return _wrapiter(_core.LLVMGetFirstBasicBlock, return wrapiter(_core.LLVMGetFirstBasicBlock,
_core.LLVMGetNextBasicBlock, self.ptr, BasicBlock) _core.LLVMGetNextBasicBlock, self.ptr, BasicBlock)
def verify(self): def verify(self):
@ -967,8 +951,8 @@ class PHINode(Instruction):
return _core.LLVMCountIncoming(self.ptr) return _core.LLVMCountIncoming(self.ptr)
def add_incoming(self, value, block): def add_incoming(self, value, block):
_check_is_value(value) check_is_value(value)
_check_is_basic_block(block) check_is_basic_block(block)
_core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr) _core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr)
def get_incoming_value(self, idx): def get_incoming_value(self, idx):
@ -984,8 +968,8 @@ class SwitchInstruction(Instruction):
Instruction.__init__(self, ptr) Instruction.__init__(self, ptr)
def add_case(self, const, bblk): def add_case(self, const, bblk):
_check_is_constant(const) # and has to be an int too check_is_constant(const) # and has to be an int too
_check_is_basic_block(bblk) check_is_basic_block(bblk)
_core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr) _core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr)
@ -1012,7 +996,7 @@ class BasicBlock(Value):
@property @property
def instructions(self): def instructions(self):
return _wrapiter(_core.LLVMGetFirstInstruction, return wrapiter(_core.LLVMGetFirstInstruction,
_core.LLVMGetNextInstruction, self.ptr, Instruction) _core.LLVMGetNextInstruction, self.ptr, Instruction)
@ -1053,29 +1037,29 @@ class Builder(object):
return Instruction(_core.LLVMBuildRetVoid(self.ptr)) return Instruction(_core.LLVMBuildRetVoid(self.ptr))
def ret(self, value): def ret(self, value):
_check_is_value(value) check_is_value(value)
return Instruction(_core.LLVMBuildRet(self.ptr, value.ptr)) return Instruction(_core.LLVMBuildRet(self.ptr, value.ptr))
def branch(self, bblk): def branch(self, bblk):
_check_is_basic_block(bblk) check_is_basic_block(bblk)
return Instruction(_core.LLVMBuildBr(self.ptr, bblk.ptr)) return Instruction(_core.LLVMBuildBr(self.ptr, bblk.ptr))
def cbranch(self, if_value, then_blk, else_blk): def cbranch(self, if_value, then_blk, else_blk):
_check_is_value(if_value) check_is_value(if_value)
_check_is_basic_block(then_blk) check_is_basic_block(then_blk)
_check_is_basic_block(else_blk) check_is_basic_block(else_blk)
return Instruction(_core.LLVMBuildCondBr(self.ptr, if_value.ptr, then_blk.ptr, else_blk.ptr)) return Instruction(_core.LLVMBuildCondBr(self.ptr, if_value.ptr, then_blk.ptr, else_blk.ptr))
def switch(self, value, else_blk, n=10): def switch(self, value, else_blk, n=10):
_check_is_value(value) check_is_value(value)
_check_is_basic_block(else_blk) check_is_basic_block(else_blk)
return SwitchInstruction(_core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n)) return SwitchInstruction(_core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n))
def invoke(self, func, args, then_blk, catch_blk, name=""): def invoke(self, func, args, then_blk, catch_blk, name=""):
_check_is_function(func) check_is_function(func)
_check_is_basic_block(then_blk) check_is_basic_block(then_blk)
_check_is_basic_block(catch_blk) check_is_basic_block(catch_blk)
args2 = _unpack_values(args) args2 = unpack_values(args)
return CallOrInvokeInstruction(_core.LLVMBuildInvoke(self.ptr, func.ptr, args2, then_blk.ptr, catch_blk.ptr, name)) return CallOrInvokeInstruction(_core.LLVMBuildInvoke(self.ptr, func.ptr, args2, then_blk.ptr, catch_blk.ptr, name))
def unwind(self): def unwind(self):
@ -1087,237 +1071,237 @@ class Builder(object):
# arithmethic-related # arithmethic-related
def add(self, lhs, rhs, name=""): def add(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name))
def sub(self, lhs, rhs, name=""): def sub(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name))
def mul(self, lhs, rhs, name=""): def mul(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name))
def udiv(self, lhs, rhs, name=""): def udiv(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def sdiv(self, lhs, rhs, name=""): def sdiv(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def fdiv(self, lhs, rhs, name=""): def fdiv(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def urem(self, lhs, rhs, name=""): def urem(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name))
def srem(self, lhs, rhs, name=""): def srem(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name))
def frem(self, lhs, rhs, name=""): def frem(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name))
def shl(self, lhs, rhs, name=""): def shl(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name))
def lshr(self, lhs, rhs, name=""): def lshr(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name))
def ashr(self, lhs, rhs, name=""): def ashr(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name))
def and_(self, lhs, rhs, name=""): def and_(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name))
def or_(self, lhs, rhs, name=""): def or_(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name))
def xor(self, lhs, rhs, name=""): def xor(self, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name))
def neg(self, val, name=""): def neg(self, val, name=""):
_check_is_value(val) check_is_value(val)
return Instruction(_core.LLVMBuildNeg(self.ptr, val.ptr, name)) return Instruction(_core.LLVMBuildNeg(self.ptr, val.ptr, name))
def not_(self, val, name=""): def not_(self, val, name=""):
_check_is_value(val) check_is_value(val)
return Instruction(_core.LLVMBuildNot(self.ptr, val.ptr, name)) return Instruction(_core.LLVMBuildNot(self.ptr, val.ptr, name))
# memory # memory
def malloc(self, ty, name=""): def malloc(self, ty, name=""):
_check_is_type(ty) check_is_type(ty)
return Instruction(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name)) return Instruction(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name))
def malloc_array(self, ty, size, name=""): def malloc_array(self, ty, size, name=""):
_check_is_type(ty) check_is_type(ty)
_check_is_value(size) check_is_value(size)
return Instruction(_core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name)) return Instruction(_core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name))
def alloca(self, ty, name=""): def alloca(self, ty, name=""):
_check_is_type(ty) check_is_type(ty)
return Instruction(_core.LLVMBuildAlloc(self.ptr, ty.ptr, name)) return Instruction(_core.LLVMBuildAlloca(self.ptr, ty.ptr, name))
def alloca_array(self, ty, size, name=""): def alloca_array(self, ty, size, name=""):
_check_is_type(ty) check_is_type(ty)
_check_is_value(size) check_is_value(size)
return Instruction(_core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name)) return Instruction(_core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name))
def free(self, ptr): def free(self, ptr):
_check_is_pointer(ptr) check_is_value(ptr)
return Instruction(_core.LLVMBuildFree(self.ptr, ptr.ptr)) return Instruction(_core.LLVMBuildFree(self.ptr, ptr.ptr))
def load(self, ptr, name=""): def load(self, ptr, name=""):
_check_is_pointer(ptr) check_is_value(ptr)
return Instruction(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name)) return Instruction(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name))
def store(self, value, ptr): def store(self, value, ptr):
_check_is_value(value) check_is_value(value)
_check_is_pointer(ptr) check_is_value(ptr)
return Instruction(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr)) return Instruction(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr))
def gep(self, ptr, indices, name=""): def gep(self, ptr, indices, name=""):
_check_is_pointer(ptr) check_is_value(ptr)
index_ptrs = _unpack_values(indices) index_ptrs = unpack_values(indices)
return Value(_core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name)) return Value(_core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name))
# casts # casts
def trunc(self, value, dest_ty, name=""): def trunc(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name))
def zext(self, value, dest_ty, name=""): def zext(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name))
def sext(self, value, dest_ty, name=""): def sext(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name))
def fptoui(self, value, dest_ty, name=""): def fptoui(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name))
def fptosi(self, value, dest_ty, name=""): def fptosi(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name))
def uitofp(self, value, dest_ty, name=""): def uitofp(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name))
def sitofp(self, value, dest_ty, name=""): def sitofp(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name))
def fptrunc(self, value, dest_ty, name=""): def fptrunc(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name))
def fpext(self, value, dest_ty, name=""): def fpext(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name))
def ptrtoint(self, value, dest_ty, name=""): def ptrtoint(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name))
def inttoptr(self, value, dest_ty, name=""): def inttoptr(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name))
def bitcast(self, value, dest_ty, name=""): def bitcast(self, value, dest_ty, name=""):
_check_is_value(value) check_is_value(value)
_check_is_type(dest_ty) check_is_type(dest_ty)
return Value(_core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name)) return Value(_core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name))
# comparisons # comparisons
def icmp(self, ipred, lhs, rhs, name=""): def icmp(self, ipred, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name))
def fcmp(self, rpred, lhs, rhs, name=""): def fcmp(self, rpred, lhs, rhs, name=""):
_check_is_value(lhs) check_is_value(lhs)
_check_is_value(rhs) check_is_value(rhs)
return Value(_core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) return Value(_core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name))
# misc # misc
def phi(self, ty, name=""): def phi(self, ty, name=""):
_check_is_type(ty) check_is_type(ty)
return PHINode(_core.LLVMBuildPhi(self.ptr, ty.ptr, name)) return PHINode(_core.LLVMBuildPhi(self.ptr, ty.ptr, name))
def call(self, fn, args, name=""): def call(self, fn, args, name=""):
_check_is_function(fn) check_is_function(fn)
arg_ptrs = _unpack_values(args) arg_ptrs = unpack_values(args)
return CallOrInvokeInstruction(_core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name)) return CallOrInvokeInstruction(_core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name))
def select(self, if_blk, then_blk, else_blk, name=""): def select(self, if_blk, then_blk, else_blk, name=""):
_check_is_basic_block(if_blk) check_is_basic_block(if_blk)
_check_is_basic_block(then_blk) check_is_basic_block(then_blk)
_check_is_basic_block(else_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, if_blk.ptr, then_blk.ptr, else_blk.ptr, name))
def vaarg(self, list_val, ty, name=""): def vaarg(self, list_val, ty, name=""):
_check_is_value(list_val) check_is_value(list_val)
_check_is_type(ty) check_is_type(ty)
return Instruction(_core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name)) return Instruction(_core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name))
def extract_element(self, vec_val, idx_val, name=""): def extract_element(self, vec_val, idx_val, name=""):
_check_is_value(vec_val) check_is_value(vec_val)
_check_is_value(idx_val) check_is_value(idx_val)
return Value(_core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, idx_val.ptr, name)) return Value(_core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, idx_val.ptr, name))
def insert_element(self, vec_val, elt_val, idx_val, name=""): def insert_element(self, vec_val, elt_val, idx_val, name=""):
_check_is_value(vec_val) check_is_value(vec_val)
_check_is_value(elt_val) check_is_value(elt_val)
_check_is_value(idx_val) check_is_value(idx_val)
return Value(_core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, elt_val.ptr, idx_val.ptr, name)) return Value(_core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, elt_val.ptr, idx_val.ptr, name))
def shuffle_vector(self, vecA, vecB, mask, name=""): def shuffle_vector(self, vecA, vecB, mask, name=""):
_check_is_value(vecA) check_is_value(vecA)
_check_is_value(vecB) check_is_value(vecB)
_check_is_value(mask) check_is_value(mask)
return Value(_core.LLVMBuildShuffleVector(self.ptr, vecA.ptr, vecB.ptr, mask.ptr, name)) return Value(_core.LLVMBuildShuffleVector(self.ptr, vecA.ptr, vecB.ptr, mask.ptr, name))
@ -1326,19 +1310,24 @@ class Builder(object):
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
class ModuleProvider(object): class ModuleProvider(llvm.Ownable):
@staticmethod @staticmethod
def new(module): def new(module):
mp = ModuleProvider(_core.LLVMCreateModuleProviderForExistingModule(module.ptr)) check_is_module(module)
module._own(mp) check_is_unowned(module)
return mp return ModuleProvider(
_core.LLVMCreateModuleProviderForExistingModule(module.ptr),
module)
def __init__(self, ptr): def __init__(self, ptr, module):
self.ptr = ptr llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModuleProvider)
module._own(self)
# a module provider is both a owner (of modules) and an ownable
# (can be owned by execution engines)
def __del__(self): def __del__(self):
_core.LLVMDisposeModuleProvider(self.ptr) llvm.Ownable.__del__(self)
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
@ -1372,48 +1361,3 @@ class MemoryBuffer(object):
def __del__(self): def __del__(self):
_core.LLVMDisposeMemoryBuffer(self.ptr) _core.LLVMDisposeMemoryBuffer(self.ptr)
#===----------------------------------------------------------------------===
# Pass manager
#===----------------------------------------------------------------------===
class PassManager(object):
@staticmethod
def new():
return PassManager(_core.LLVMCreatePassManager())
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposePassManager(self.ptr)
def run(self, module):
_check_is_module(module)
return _core.LLVMRunPassManager(self.ptr, module.ptr)
class FunctionPassManager(PassManager):
@staticmethod
def new(mp):
_check_is_module_provider(mp)
return FunctionPassManager(_core.LLVMCreateFunctionPassManager(mp.ptr))
def __init__(self, ptr):
PassManager.__init__(self, ptr)
def __del__(self):
PassManager.__del__(self)
def initialize(self):
_core.LLVMInitializeFunctionPassManager(self.ptr)
def run(self, fn):
_check_is_function(fn)
return _core.LLVMRunFunctionPassManager(fn.ptr)
def finalize(self):
_core.LLVMFinalizeFunctionPassManager(self.ptr)

View file

@ -2,50 +2,61 @@
""" """
import llvm, core import llvm # top-level, for common stuff
from _util import * import core # module provider, function etc.
import _core import _core # C wrappers
from _util import * # utility functions
#===----------------------------------------------------------------------===
# Target data
#===----------------------------------------------------------------------===
class TargetData(llvm.Ownable):
@staticmethod
def new(strrep):
return TargetData(_core.LLVMCreateTargetData(strrep))
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)
#===----------------------------------------------------------------------===
# Execution engine
#===----------------------------------------------------------------------===
class ExecutionEngine(object): class ExecutionEngine(object):
@staticmethod @staticmethod
def new(mp, force_interpreter=False): def new(mp, force_interpreter=False):
check_is_module_provider(mp) check_is_module_provider(mp)
ret = _core.LLVMCreateExecutionEngine(mp.ptr, int(create_interpreter)) check_is_unowned(mp)
ret = _core.LLVMCreateExecutionEngine(mp.ptr, int(force_interpreter))
if isinstance(ret, str): if isinstance(ret, str):
raise llvm.LLVMException, str raise llvm.LLVMException, ret
return ExecutionEngine(ret) return ExecutionEngine(ret, mp)
def __init__(self, ptr): def __init__(self, ptr, mp):
self.ptr = ptr self.ptr = ptr
mp._own(self)
def __del__(self): def __del__(self):
_core.LLVMDisposeExecutionEngine(self.ptr) _core.LLVMDisposeExecutionEngine(self.ptr)
def run_static_constructors(self):
_core.LLVMRunStaticConstructors(self.ptr)
def run_static_destructors(self):
_core.LLVMRunStaticDestructors(self.ptr)
def run_function_as_main(self, fn, argv, envp):
check_is_function(fn)
_core.LLVMRunFunctionAsMain(self.ptr, fn.ptr, argv, envp)
def run_function(self, fn, args): def run_function(self, fn, args):
check_is_function(fn) check_is_function(fn)
return _core.LLVMRunFunction(self.ptr, fn.ptr, args) return _core.LLVMRunFunction(self.ptr, fn.ptr, args)
def free_machine_code_for_function(self, fn):
check_is_function(fn)
_core.LLVMFreeMachineCodeForFunction(self.ptr, fn.ptr)
def add_module_provider(self, mp):
pass
def remove_module_provider(self):
pass
@property @property
def target_data(self): def target_data(self):
return TargetData(_core.LLVMGetExecutionEngineTargetData(self.ptr)) td = TargetData(_core.LLVMGetExecutionEngineTargetData(self.ptr))
td._own(self)
return td

View file

@ -1,6 +1,11 @@
"""Pass managers and passes.
"""
import ee # target data
import _core # C wrappers
from _util import * # utility functions
from _util import *
import _core
# passes # passes
PASS_CONSTANT_PROPAGATION = 1 PASS_CONSTANT_PROPAGATION = 1
@ -43,9 +48,19 @@ class PassManager(object):
def __del__(self): def __del__(self):
_core.LLVMDisposePassManager(self.ptr) _core.LLVMDisposePassManager(self.ptr)
def add(self, pass_id): def add(self, tgt_data_or_pass_id):
assert pass_id in _pass_creator, 'Invalid pass_id ("' + str(pass_id) + '")' if isinstance(tgt_data_or_pass_id, ee.TargetData):
cfn = _pass_creator[pass_id] # KeyError => pass_id is invalid self._add_target_data(tgt_data_or_pass_id)
elif tgt_data_or_pass_id in _pass_creator:
self._add_pass(tgt_data_or_pass_id)
else:
raise LLVMException, "invalid pass_id"
def _add_target_data(self, tgt):
_core.LLVMAddTargetData(tgt.ptr, self.ptr)
def _add_pass(self, pass_id):
cfn = _pass_creator[pass_id]
cfn(self.ptr) cfn(self.ptr)
def run(self, module): def run(self, module):
@ -70,8 +85,8 @@ class FunctionPassManager(PassManager):
_core.LLVMInitializeFunctionPassManager(self.ptr) _core.LLVMInitializeFunctionPassManager(self.ptr)
def run(self, fn): def run(self, fn):
_check_is_function(fn) check_is_function(fn)
return _core.LLVMRunFunctionPassManager(fn.ptr) return _core.LLVMRunFunctionPassManager(self.ptr, fn.ptr)
def finalize(self): def finalize(self):
_core.LLVMFinalizeFunctionPassManager(self.ptr) _core.LLVMFinalizeFunctionPassManager(self.ptr)

View file

@ -74,6 +74,9 @@ PyObject *ctor_int(int i)
return PyInt_FromLong(i); return PyInt_FromLong(i);
} }
_define_std_ctor(LLVMExecutionEngineRef)
_define_std_ctor(LLVMTargetDataRef)
/*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
/* Helper functions */ /* Helper functions */

View file

@ -13,6 +13,8 @@
/* llvm includes */ /* llvm includes */
#include "llvm-c/Core.h" #include "llvm-c/Core.h"
#include "llvm-c/Analysis.h" #include "llvm-c/Analysis.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
/*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
@ -56,6 +58,20 @@ PyObject *ctor_LLVMPassManagerRef(LLVMPassManagerRef p);
/* standard types */ /* standard types */
PyObject *ctor_int(int i); PyObject *ctor_int(int i);
#define _declare_std_ctor(typ) \
PyObject * ctor_ ## typ ( typ p);
#define _define_std_ctor(typ) \
PyObject * ctor_ ## typ ( typ p) \
{ \
if (p) \
return PyCObject_FromVoidPtr(p, NULL); \
Py_RETURN_NONE; \
}
_declare_std_ctor(LLVMExecutionEngineRef)
_declare_std_ctor(LLVMTargetDataRef)
/*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
/* Helper methods */ /* Helper methods */
@ -257,6 +273,22 @@ _w ## func (PyObject *self, PyObject *args) \
return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ return ctor_ ## outtype ( func (arg1, arg2, arg3)); \
} }
/**
* Wrap LLVM functions of the type
* outtype func(const char *s)
*/
#define _wrap_str2obj(func, outtype) \
static PyObject * \
_w ## func (PyObject *self, PyObject *args) \
{ \
const char *arg1; \
\
if (!PyArg_ParseTuple(args, "s", &arg1)) \
return NULL; \
\
return ctor_ ## outtype ( func (arg1)); \
}
/** /**
* Wrap LLVM functions of the type * Wrap LLVM functions of the type
* outtype func() * outtype func()

View file

@ -17,7 +17,8 @@ def get_libs_and_objs(llvm_config, components):
libs.append(part[2:]) libs.append(part[2:])
else: else:
assert part.endswith('.o') assert part.endswith('.o')
objs.append(part[:-2]) # objs.append(part[:-2])
objs.append(part) # eh, looks like we need the .o after all
return (libs, objs) return (libs, objs)
@ -42,8 +43,11 @@ def get_llvm_config():
def call_setup(llvm_config): def call_setup(llvm_config):
incdir = _run(llvm_config + ' --includedir') incdir = _run(llvm_config + ' --includedir')
libdir = _run(llvm_config + ' --libdir')
ldflags = _run(llvm_config + ' --ldflags') ldflags = _run(llvm_config + ' --ldflags')
libs_core, objs_core = get_libs_and_objs(llvm_config, ['core', 'analysis', 'scalaropts']) libs_core, objs_core = get_libs_and_objs(llvm_config,
['core', 'analysis', 'scalaropts', 'executionengine',
'jit', 'native'])
std_libs = [ 'pthread', 'dl', 'm' ] std_libs = [ 'pthread', 'dl', 'm' ]
@ -54,7 +58,7 @@ def call_setup(llvm_config):
('__STDC_LIMIT_MACROS', None), ('__STDC_LIMIT_MACROS', None),
('_GNU_SOURCE', None)], ('_GNU_SOURCE', None)],
include_dirs = [incdir], include_dirs = [incdir],
library_dirs = [ '/home/mdevan/llvm/Release/lib' ], library_dirs = [libdir],
libraries = std_libs + libs_core, libraries = std_libs + libs_core,
extra_objects = objs_core) extra_objects = objs_core)

View file

@ -26,18 +26,18 @@ entry = func.append_basic_block("entry")
builder = Builder.new() builder = Builder.new()
builder.position_at_end(entry) builder.position_at_end(entry)
# add two args into temp1 # add two args into tmp1
temp1 = builder.add(func.args[0], func.args[1], "temp1") tmp1 = builder.add(func.args[0], func.args[1], "tmp1")
# sub `1' from that # sub `1' from that
one = Constant.real( ty_double, 1.0 ) one = Constant.real( ty_double, 1.0 )
temp2 = builder.sub(temp1, one, "temp2") tmp2 = builder.sub(tmp1, one, "tmp2")
# convert to integer # convert to integer
temp3 = builder.fptoui(temp2, ty_int, "temp3") tmp3 = builder.fptoui(tmp2, ty_int, "tmp3")
# return it # return it
builder.ret(temp3) builder.ret(tmp3)
# dump the module to see the bc # dump the module to see the llvm "assembly" code
module.dump() print module

View file

@ -5,6 +5,7 @@ import gc
import unittest, sys import unittest, sys
from llvm import *
from llvm.core import * from llvm.core import *
class TestModule(unittest.TestCase): class TestModule(unittest.TestCase):
@ -23,6 +24,7 @@ class TestModule(unittest.TestCase):
m = Module.new("temp_m") m = Module.new("temp_m")
return ModuleProvider.new(m) return ModuleProvider.new(m)
# check basic ownership and deletion
m = Module.new("test1.1") m = Module.new("test1.1")
self.assertEqual(m.owner, None) self.assertEqual(m.owner, None)
mp = ModuleProvider.new(m) mp = ModuleProvider.new(m)
@ -34,14 +36,19 @@ class TestModule(unittest.TestCase):
m = None m = None
self.assertEqual(gc.garbage, []) self.assertEqual(gc.garbage, [])
# delete a module which was owned by a module provider that has
# gone out of scope
m2 = Module.new("test1.2") m2 = Module.new("test1.2")
temp_mp(m2) temp_mp(m2)
del m2 del m2
self.assertEqual(gc.garbage, []) self.assertEqual(gc.garbage, [])
# delete a module provider object which owned a module that has
# gone out of scope
mp3 = temp_m() mp3 = temp_m()
mp3 = None mp3 = None
# check ref counts
m4 = Module.new("test1.4") m4 = Module.new("test1.4")
self.assertEqual(sys.getrefcount(m4), 1+1) self.assertEqual(sys.getrefcount(m4), 1+1)
mp4 = ModuleProvider.new(m4) mp4 = ModuleProvider.new(m4)
@ -51,14 +58,16 @@ class TestModule(unittest.TestCase):
self.assertEqual(sys.getrefcount(mp4), 1+1) self.assertEqual(sys.getrefcount(mp4), 1+1)
mp4 = None mp4 = None
own_works = False # cannot create a second module provider object for the same
# module
works = False
m5 = Module.new("test1.5") m5 = Module.new("test1.5")
mp5 = ModuleProvider.new(m5) mp5 = ModuleProvider.new(m5)
try: try:
m5._own(None) mp5_2 = ModuleProvider.new(m5)
except AssertionError: except LLVMException:
own_works = True works = True
self.assertEqual(own_works, True) self.assertEqual(works, True)
def testdata_layout(self): def testdata_layout(self):
@ -70,6 +79,7 @@ class TestModule(unittest.TestCase):
reqd = '; ModuleID = \'test2.1\'\ntarget datalayout = "some_value"\n' reqd = '; ModuleID = \'test2.1\'\ntarget datalayout = "some_value"\n'
self.assertEqual(str(m), reqd) self.assertEqual(str(m), reqd)
def testtarget(self): def testtarget(self):
"""Target property.""" """Target property."""
m = Module.new("test3.1") m = Module.new("test3.1")
@ -79,6 +89,7 @@ class TestModule(unittest.TestCase):
reqd = '; ModuleID = \'test3.1\'\ntarget triple = "some_value"\n' reqd = '; ModuleID = \'test3.1\'\ntarget triple = "some_value"\n'
self.assertEqual(str(m), reqd) self.assertEqual(str(m), reqd)
def testtype_name(self): def testtype_name(self):
"""Type names.""" """Type names."""
m = Module.new("test4.1") m = Module.new("test4.1")
@ -95,15 +106,16 @@ class TestModule(unittest.TestCase):
reqd = "; ModuleID = 'test4.1'\n" reqd = "; ModuleID = 'test4.1'\n"
self.assertEqual(str(m), reqd) self.assertEqual(str(m), reqd)
def testglobal_variable(self): def testglobal_variable(self):
"""Global variables.""" """Global variables."""
m = Module.new("test5.1") m = Module.new("test5.1")
t = Type.int() t = Type.int()
gv = m.add_global_variable(t, "gv") gv = m.add_global_variable(t, "gv")
print m
self.assertNotEqual(gv, None) self.assertNotEqual(gv, None)
self.assertEqual(gv.name, "gv") self.assertEqual(gv.name, "gv")
self.assertEqual(gv.type, t) self.assertEqual(gv.type, Type.pointer(t))
def main(): def main():
gc.set_debug(gc.DEBUG_LEAK) gc.set_debug(gc.DEBUG_LEAK)

View file

@ -4,12 +4,13 @@ About
[NOTE] [NOTE]
._llvm-py_ Mission Statement ._llvm-py_ Mission Statement
======================================================================= =======================================================================
Provide a simple, consistent and well-documented suite of APIs Provide a simple, consistent and well-documented suite of APIs that
that exposes just enough of LLVM to write a compiler/interpreter/VM exposes just enough of LLVM to write a compiler/VM in Python.
in Python.
======================================================================= =======================================================================
_llvm-py_ is developed by Mahadevan R, in his spare time, without being _llvm-py_ is developed by Mahadevan R, in his spare time, without being
paid for it. He can be reached at _mdevan.foobar .at. gmail.com_, on the paid for it. He can be reached at _mdevan.foobar .at. gmail.com_, on the
llvm-dev mailing list and irc.oftc.net#llvm (mdevan). llvm-dev mailing list and irc.oftc.net#llvm (mdevan).
These web pages were generated using the nifty tool
http://www.methods.co.nz/asciidoc/[asciidoc].

View file

@ -6,9 +6,8 @@ grow up. Please contribute! All patches are welcome.
The _llvm-py_ code is hosted on a google code project by the same name, The _llvm-py_ code is hosted on a google code project by the same name,
http://code.google.com/p/llvm-py/[here]. It provides the SVN repository http://code.google.com/p/llvm-py/[here]. It provides the SVN repository
and a http://code.google.com/p/llvm-py/issues/list[bug tracker]. and a http://code.google.com/p/llvm-py/issues/list[bug tracker]. The
latest code can be checked out from SVN like so:
The latest code can be checked out from SVN like so:
---- ----
$ svn checkout http://llvm-py.googlecode.com/svn/trunk/ llvm-py $ svn checkout http://llvm-py.googlecode.com/svn/trunk/ llvm-py

View file

@ -1,7 +1,7 @@
Download and Setup Download and Setup
================== ==================
The latest release is 0.2, released xx-Jun-2008 (full link:changelog[Changelog] The latest release is 0.2, released xx-Jun-2008 (full link:#changelog[Changelog]
below). below).
Download it here: Download it here:
@ -10,8 +10,8 @@ Download it here:
````~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ````~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Release,Date,Package,Mirror Release,Date,Package,Mirror
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0.2,xx-xxx-2008,http://link1/[llvm-py-0.2.tar.bz2],http://link1/[llvm-py-0.2.tar.bz2] 0.2,xx-May-2008,http://llvm-py.googlecode.com/files/llvm-py-0.2.tar.bz2[llvm-py-0.2.tar.bz2],link:llvm-py-0.2.tar.bz2[llvm-py-0.2.tar.bz2]
0.1,xx-xxx-2008,http://link1/[llvm-py-0.1.tar.bz2],http://link1/[llvm-py-0.1.tar.bz2] 0.1,20-May-2008,http://llvm-py.googlecode.com/files/llvm-py-0.1.tar.bz2[llvm-py-0.1.tar.bz2],link:llvm-py-0.1.tar.bz2[llvm-py-0.1.tar.bz2]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -32,6 +32,7 @@ Setting Up
Follow these steps to get _llvm-py_ up and running: Follow these steps to get _llvm-py_ up and running:
* link:#uninstall[Uninstall] any previous version of _llvm-py_.
* Get and build LLVM. * Get and build LLVM.
* Optionally, install it. * Optionally, install it.
* Get the latest release (see above) of _llvm-py_ and untar it: * Get the latest release (see above) of _llvm-py_ and untar it:
@ -54,11 +55,28 @@ $ sudo python setup.py install --llvm-config=/path/to/llvm-config
That's it! That's it!
NOTE: _setup.py_ is a standard Python distutils script. See the Python .Notes:
documentation regarding http://docs.python.org/inst/inst.html[Installing - _setup.py_ is a standard Python distutils script. See the Python
Python Modules] and http://docs.python.org/dist/dist.html[Distributing documentation regarding
Python Modules] for more information on such scripts. 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.
- To build the debug version, build with the +-g+ flag and the debug
version of llvm-config:
+
----
$ python setup.py build -g --llvm-config=/path/to/Debug/bin/llvm-config
$ sudo python setup.py install
----
- Debug binaries are _huge_! (65 MB+)
- If +++--llvm-config+++ is not specified, +setup.py+ looks for
+llvm-config+ in the +PATH+, which will succeed if LLVM is installed.
[[uninstall]]
Uninstall Uninstall
--------- ---------
@ -69,8 +87,9 @@ To get rid of llvm-py completely, if you wish to do so:
# rm -f /usr/lib/python2.5/site-packages/llvm_py-0.1.egg-info # rm -f /usr/lib/python2.5/site-packages/llvm_py-0.1.egg-info
---- ----
You'll need to be root to do this. Paths are for debian-based systems, - You need to be root to do this.
in other distros it might be different. - Paths are for debian-based systems, in other distros it might be different.
- Note that there is a version number in the egg file name.
[[changelog]] [[changelog]]
@ -78,5 +97,5 @@ Changelog
---------- ----------
---- ----
include::changelog[] include::../../CHANGELOG[]
---- ----

View file

@ -5,49 +5,7 @@ Here's an example:
[python] [python]
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python include::../../test/example.py[]
from llvm.core import *
## create a module
module = Module.new("my_module")
## create a function type taking two doubles and returning a (32-bit) integer
ty_double = Type.double()
ty_int = Type.int()
ty_func = Type.function( ty_int, [ ty_double, ty_double ] )
## create a function of this type
func = Function.new( module, ty_func, "foobar" )
# name function args
func.args[0].name = "arg1"
func.args[1].name = "arg2"
## implement the function
# add a basic block
entry = func.append_basic_block("entry")
# create an llvm::IRBuilder
builder = Builder.new()
builder.position_at_end(entry)
# add two args into temp1
temp1 = builder.add(func.args[0], func.args[1], "temp1")
# sub `1' from that
one = Constant.real( ty_double, 1.0 )
temp2 = builder.sub(temp1, one, "temp2")
# convert to integer
temp3 = builder.fptoui(temp2, ty_int, "temp3")
# return it
builder.ret(temp3)
# dump the module to see the bc
module.dump()
source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
which gives this output: which gives this output: