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:
parent
6ee3298bd2
commit
2255a7e5dd
15 changed files with 559 additions and 396 deletions
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
104
llvm/_core.c
104
llvm/_core.c
|
|
@ -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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
492
llvm/core.py
492
llvm/core.py
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
|
||||||
67
llvm/ee.py
67
llvm/ee.py
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
32
llvm/wrap.h
32
llvm/wrap.h
|
|
@ -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()
|
||||||
|
|
|
||||||
10
setup.py
10
setup.py
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
26
test/test.py
26
test/test.py
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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].
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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[]
|
||||||
----
|
----
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue