llvmpy/llvm/core.py
mdevan.foobar 9cc8fdc0cd Build cleanly with LLVM 2.3 or 2.3svn.
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@15 8d1e9007-1d4e-0410-b67e-1979fd6579aa
2008-06-18 16:31:35 +00:00

1476 lines
45 KiB
Python

"""Core classes of LLVM.
The llvm.core module contains classes and constants required to build the
in-memory intermediate representation (IR) data structures."""
import llvm # top-level, for common stuff
import _core # C wrappers
from _util import * # utility functions
#===----------------------------------------------------------------------===
# Enumerations
#===----------------------------------------------------------------------===
# type kinds
TYPE_VOID = 0
TYPE_FLOAT = 1
TYPE_DOUBLE = 2
TYPE_X86_FP80 = 3
TYPE_FP128 = 4
TYPE_PPC_FP128 = 5
TYPE_LABEL = 6
TYPE_INTEGER = 7
TYPE_FUNCTION = 8
TYPE_STRUCT = 9
TYPE_ARRAY = 10
TYPE_POINTER = 11
TYPE_OPAQUE = 12
TYPE_VECTOR = 13
# calling conventions
CC_C = 0
CC_FASTCALL = 8
CC_COLDCALL = 9
CC_X86_STDCALL = 64
CC_X86_FASTCALL = 65
# int predicates
IPRED_EQ = 32
IPRED_NE = 33
IPRED_UGT = 34
IPRED_UGE = 35
IPRED_ULT = 36
IPRED_ULE = 37
IPRED_SGT = 38
IPRED_SGE = 39
IPRED_SLT = 40
IPRED_SLE = 41
# real predicates
RPRED_FALSE = 0
RPRED_OEQ = 1
RPRED_OGT = 2
RPRED_OGE = 3
RPRED_OLT = 4
RPRED_OLE = 5
RPRED_ONE = 6
RPRED_ORD = 7
RPRED_UNO = 8
RPRED_UEQ = 9
RPRED_UGT = 10
RPRED_UGE = 11
RPRED_ULT = 12
RPRED_ULE = 13
RPRED_UNE = 14
RPRED_TRUE = 15
# linkages
LINKAGE_EXTERNAL = 0
LINKAGE_LINKONCE = 1
LINKAGE_WEAK = 2
LINKAGE_APPENDING = 3
LINKAGE_INTERNAL = 4
LINKAGE_DLLIMPORT = 5
LINKAGE_DLLEXPORT = 6
LINKAGE_EXTERNAL_WEAK = 7
LINKAGE_GHOST = 8
# visibility
VISIBILITY_DEFAULT = 0
VISIBILITY_HIDDEN = 1
VISIBILITY_PROTECTED = 2
# parameter attributes
ATTR_ZEXT = 1
ATTR_SEXT = 2
ATTR_NO_RETURN = 4
ATTR_IN_REG = 8
ATTR_STRUCT_RET = 16
ATTR_NO_UNWIND = 32
ATTR_NO_ALIAS = 64
ATTR_BY_VAL = 128
ATTR_NEST = 256
ATTR_READ_NONE = 512
ATTR_READONLY = 1024
#===----------------------------------------------------------------------===
# Module
#===----------------------------------------------------------------------===
class Module(llvm.Ownable):
"""A Module instance stores all the information related to an LLVM module.
Modules are the top level container of all other LLVM Intermediate
Representation (IR) objects. Each module directly contains a list of
globals variables, a list of functions, a list of libraries (or
other modules) this module depends on, a symbol table, and various
data about the target's characteristics.
Construct a Module only using the static methods defined below, *NOT*
using the constructor. A correct usage is:
module_obj = Module.new('my_module')
"""
@staticmethod
def new(id):
"""Create a new Module instance.
Creates an instance of Module, having the id `id'.
"""
return Module(_core.LLVMModuleCreateWithName(id))
def __init__(self, ptr):
"""DO NOT CALL DIRECTLY.
Use the static method `Module.new' instead.
"""
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule)
def __str__(self):
"""Text representation of a module.
Returns the textual representation (`llvm assembly') of the
module. Use it like this:
ll = str(module_obj)
print module_obj # same as `print ll'
"""
return _core.LLVMDumpModuleToString(self.ptr)
def __eq__(self, rhs):
if isinstance(rhs, Module):
return str(self) == str(rhs)
else:
return False
def _get_target(self):
return _core.LLVMGetTarget(self.ptr)
def _set_target(self, value):
return _core.LLVMSetTarget(self.ptr, value)
target = property(_get_target, _set_target,
"""The target triple string describing the target host."""
)
def _get_data_layout(self):
return _core.LLVMGetDataLayout(self.ptr)
def _set_data_layout(self, value):
_core.LLVMSetDataLayout(self.ptr, value)
data_layout = property(_get_data_layout, _set_data_layout,
"""The data layout string for the module's target platform.
The data layout strings is an encoded representation of
the type sizes and alignments expected by this module.
"""
)
def add_type_name(self, name, ty):
"""Map a string to a type.
Similar to C's struct/typedef declarations. Returns True
if entry already existed (in which case nothing is changed),
False otherwise.
"""
check_is_type(ty)
return _core.LLVMAddTypeName(self.ptr, name, ty.ptr) != 0
def delete_type_name(self, name):
"""Removes a named type.
Undoes what add_type_name() does.
"""
_core.LLVMDeleteTypeName(self.ptr, name)
def add_global_variable(self, ty, name):
"""Add a global variable of given type with given name."""
return GlobalVariable.new(self, ty, name)
def get_global_variable_named(self, name):
"""Return a GlobalVariable object for the given name."""
return GlobalVariable.get(self, name)
@property
def global_variables(self):
"""All global variables in this module.
This property returns a generator that yields GlobalVariable
objects. Use it like this:
for gv in module_obj.global_variables:
# gv is an instance of GlobalVariable
# do stuff with gv
"""
return wrapiter(_core.LLVMGetFirstGlobal, _core.LLVMGetNextGlobal,
self.ptr, GlobalVariable, [self])
def add_function(self, ty, name):
"""Add a function of given type with given name."""
return Function.new(self, ty, name)
def get_function_named(self, name):
"""Return a Function object representing function with given name."""
return Function.get(self, name)
@property
def functions(self):
"""All functions in this module.
This property returns a generator that yields Function objects.
Use it like this:
for f in module_obj.functions:
# f is an instance of Function
# do stuff with f
"""
return wrapiter(_core.LLVMGetFirstFunction,
_core.LLVMGetNextFunction, self.ptr, Function, [self])
def verify(self):
"""Verify module.
Checks module for errors. Raises `llvm.LLVMException' on any
error."""
ret = _core.LLVMVerifyModule(self.ptr)
if ret != "":
raise llvm.LLVMException, ret
#===----------------------------------------------------------------------===
# Types
#===----------------------------------------------------------------------===
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
def int(bits=32):
"""Create an integer type having the given bit width."""
if bits == 1:
return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER)
elif bits == 8:
return _make_type(_core.LLVMInt8Type(), TYPE_INTEGER)
elif bits == 16:
return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER)
elif bits == 32:
return _make_type(_core.LLVMInt32Type(), TYPE_INTEGER)
elif bits == 64:
return _make_type(_core.LLVMInt64Type(), TYPE_INTEGER)
else:
bits = int(bits) # bits must be an int
return _make_type(_core.LLVMIntType(bits), TYPE_INTEGER)
@staticmethod
def float():
"""Create a 32-bit floating point type."""
return _make_type(_core.LLVMFloatType(), TYPE_FLOAT)
@staticmethod
def double():
"""Create a 64-bit floating point type."""
return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE)
@staticmethod
def x86_fp80():
"""Create a 80-bit x86 floating point type."""
return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80)
@staticmethod
def fp128():
"""Create a 128-bit floating point type (with 112-bit
mantissa)."""
return _make_type(_core.LLVMFP128Type(), TYPE_FP128)
@staticmethod
def ppc_fp128():
"""Create a 128-bit floating point type (two 64-bits)."""
return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128)
@staticmethod
def function(return_ty, param_tys, var_arg=False):
"""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
params = unpack_types(param_tys)
return _make_type(_core.LLVMFunctionType(return_ty.ptr, params,
var_arg), TYPE_FUNCTION)
@staticmethod
def struct(element_tys): # not packed
"""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 the packed_struct() method."""
elems = unpack_types(element_tys)
return _make_type(_core.LLVMStructType(elems, 0), TYPE_STRUCT)
@staticmethod
def packed_struct(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 the struct() method."""
elems = unpack_types(element_tys)
return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT)
@staticmethod
def array(element_ty, count):
"""Create an array type.
Creates a type for an array of elements of type `element_ty',
having 'count' elements."""
check_is_type(element_ty)
count = int(count) # must be an int
return _make_type(_core.LLVMArrayType(element_ty.ptr, count),
TYPE_ARRAY)
@staticmethod
def pointer(pointee_ty, addr_space=0):
"""Create a pointer type.
Creates a pointer type, which can point to values of type
`pointee_ty', in the address space `addr_space'."""
check_is_type(pointee_ty)
addr_space = int(addr_space) # must be an int
return _make_type(_core.LLVMPointerType(pointee_ty.ptr,
addr_space), TYPE_POINTER)
@staticmethod
def vector(element_ty, count):
"""Create a vector type.
Creates a type for a vector of elements of type `element_ty',
having `count' elements."""
check_is_type(element_ty)
count = int(count) # must be an int
return _make_type(_core.LLVMVectorType(element_ty.ptr, count),
TYPE_VECTOR)
@staticmethod
def void():
"""Create a void type.
Represents the `void' type."""
return _make_type(_core.LLVMVoidType(), TYPE_VOID)
@staticmethod
def label():
"""Create a label type."""
return _make_type(_core.LLVMLabelType(), TYPE_LABEL)
@staticmethod
def opaque():
"""Create an opaque type.
Opaque types are used to create self-referencing types."""
return _make_type(_core.LLVMOpaqueType(), TYPE_OPAQUE)
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods instead."""
self.ptr = ptr
self.kind = kind
"""An enum (int) value denoting which type this is.
Use the symbolic constants TYPE_* defined in llvm.core
module."""
def __str__(self):
"""Text representation of a type.
Returns the textual representation (`llvm assembly') of the type."""
return _core.LLVMDumpTypeToString(self.ptr)
def __eq__(self, rhs):
if isinstance(rhs, Type):
return str(self) == str(rhs)
else:
return False
def refine(self, dest):
"""Refine the abstract type represented by self into a concrete class.
This object is no longer valid after refining, so do not hold references
to it after calling. See the user guide for examples on how to use this."""
check_is_type(dest)
_core.LLVMRefineType(self.ptr, dest.ptr)
self.ptr = None
class IntegerType(Type):
"""Represents an integer type."""
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def width(self):
"""The width of the integer type, in bits."""
return _core.LLVMGetIntTypeWidth(self.ptr)
class FunctionType(Type):
"""Represents a function type."""
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def return_type(self):
"""The type of the value returned by this function."""
ptr = _core.LLVMGetReturnType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def vararg(self):
"""True if this function is variadic."""
return _core.LLVMIsFunctionVarArg(self.ptr) != 0
@property
def args(self):
"""An iterable that yields Type objects, representing the types of the
arguments accepted by this function, in order."""
pp = _core.LLVMGetFunctionTypeParams(self.ptr)
return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ]
@property
def arg_count(self):
"""Number of arguments accepted by this function.
Same as len(obj.args), but faster."""
return _core.LLVMCountParamTypes(self.ptr)
class StructType(Type):
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def element_count(self):
return _core.LLVMCountStructElementTypes(self.ptr)
@property
def elements(self):
pp = _core.LLVMGetStructElementTypes(self.ptr)
return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ]
@property
def packed(self):
return _core.LLVMIsPackedStruct(self.ptr) != 0
class ArrayType(Type):
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def element(self):
ptr = _core.LLVMGetElementType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def count(self):
return _core.LLVMGetArrayLength(self.ptr)
class PointerType(Type):
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def address_space(self):
return _core.LLVMGetPointerAddressSpace(self.ptr)
class VectorType(Type):
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
Use one of the static methods of the *base* class (Type) instead."""
Type.__init__(self, ptr, kind)
@property
def element(self):
ptr = _core.LLVMGetElementType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def count(self):
return _core.LLVMGetVectorSize(self.ptr)
def _make_type(ptr, kind):
if kind == TYPE_INTEGER:
return IntegerType(ptr, kind)
elif kind == TYPE_FUNCTION:
return FunctionType(ptr, kind)
elif kind == TYPE_STRUCT:
return StructType(ptr, kind)
elif kind == TYPE_ARRAY:
return ArrayType(ptr, kind)
elif kind == TYPE_POINTER:
return PointerType(ptr, kind)
elif kind == TYPE_VECTOR:
return VectorType(ptr, kind)
else:
return Type(ptr, kind)
#===----------------------------------------------------------------------===
# Type Handle
#===----------------------------------------------------------------------===
class TypeHandle(object):
@staticmethod
def new(abstract_ty):
check_is_type(abstract_ty)
return TypeHandle(_core.LLVMCreateTypeHandle(abstract_ty.ptr))
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeTypeHandle(self.ptr)
@property
def type(self):
ptr = _core.LLVMResolveTypeHandle(self.ptr)
return _make_type(ptr, _core.LLVMGetTypeKind(ptr))
#===----------------------------------------------------------------------===
# Values
#===----------------------------------------------------------------------===
class Value(object):
def __init__(self, ptr):
self.ptr = ptr
def __str__(self):
return _core.LLVMDumpValueToString(self.ptr)
def __eq__(self, rhs):
if isinstance(rhs, Value):
return str(self) == str(rhs)
else:
return False
def get_name(self):
return _core.LLVMGetValueName(self.ptr)
def set_name(self, value):
return _core.LLVMSetValueName(self.ptr, value)
name = property(get_name, set_name)
@property
def type(self):
ptr = _core.LLVMTypeOf(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
class Constant(Value):
@staticmethod
def null(ty):
check_is_type(ty)
return Constant(_core.LLVMConstNull(ty.ptr));
@staticmethod
def all_ones(ty):
check_is_type(ty)
return Constant(_core.LLVMConstAllOnes(ty.ptr));
@staticmethod
def undef(ty):
check_is_type(ty)
return Constant(_core.LLVMGetUndef(ty.ptr));
@staticmethod
def int(ty, value):
check_is_type(ty)
return Constant(_core.LLVMConstInt(ty.ptr, value, 0))
@staticmethod
def int_signextend(ty, value):
check_is_type(ty)
return Constant(_core.LLVMConstInt(ty.ptr, value, 1))
@staticmethod
def real(ty, value):
check_is_type(ty)
if isinstance(value, str):
return Constant(_core.LLVMConstRealOfString(ty.ptr, value))
else:
return Constant(_core.LLVMConstReal(ty.ptr, value))
@staticmethod
def string(strval): # dont_null_terminate=True
return Constant(_core.LLVMConstString(strval, 1))
@staticmethod
def stringz(strval): # dont_null_terminate=False
return Constant(_core.LLVMConstString(strval, 0))
@staticmethod
def array(ty, consts):
check_is_type(ty)
const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstArray(ty.ptr, const_ptrs))
@staticmethod
def struct(consts): # not packed
const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstStruct(const_ptrs, 0))
@staticmethod
def packed_struct(consts):
const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstStruct(const_ptrs, 1))
@staticmethod
def vector(consts):
const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstVector(const_ptrs))
@staticmethod
def sizeof(ty):
check_is_type(ty)
return Constant(_core.LLVMSizeOf(ty.ptr))
def __init__(self, ptr):
Value.__init__(self, ptr)
def neg(self):
return Constant(_core.LLVMConstNeg(self.ptr))
def not_(self):
return Constant(_core.LLVMConstNot(self.ptr))
def add(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstAdd(self.ptr, rhs.ptr))
def sub(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstSub(self.ptr, rhs.ptr))
def mul(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstMul(self.ptr, rhs.ptr))
def udiv(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstUDiv(self.ptr, rhs.ptr))
def sdiv(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstSDiv(self.ptr, rhs.ptr))
def fdiv(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstFDiv(self.ptr, rhs.ptr))
def urem(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstURem(self.ptr, rhs.ptr))
def srem(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstSRem(self.ptr, rhs.ptr))
def frem(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstFRem(self.ptr, rhs.ptr))
def and_(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstAnd(self.ptr, rhs.ptr))
def or_(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstOr(self.ptr, rhs.ptr))
def xor(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstXor(self.ptr, rhs.ptr))
def icmp(self, int_pred, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstICmp(int_pred, self.ptr, rhs.ptr))
def fcmp(self, real_pred, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstFCmp(real_pred, self.ptr, rhs.ptr))
# after LLVM 2.3!
# def vicmp(self, int_pred, rhs):
# check_is_constant(rhs)
# return Constant(_core.LLVMConstVICmp(int_pred, self.ptr, rhs.ptr))
#
# def vfcmp(self, real_pred, rhs):
# check_is_constant(rhs)
# return Constant(_core.LLVMConstVFCmp(real_pred, self.ptr, rhs.ptr))
def shl(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstShl(self.ptr, rhs.ptr))
def lshr(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstLShr(self.ptr, rhs.ptr))
def ashr(self, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstAShr(self.ptr, rhs.ptr))
def gep(self, indices):
index_ptrs = unpack_constants(indices)
return Constant(_core.LLVMConstGEP(self.ptr, index_ptrs))
def trunc(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstTrunc(self.ptr, ty.ptr))
def sext(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstSExt(self.ptr, ty.ptr))
def zext(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstZExt(self.ptr, ty.ptr))
def fptrunc(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstFPTrunc(self.ptr, ty.ptr))
def fpext(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstFPExt(self.ptr, ty.ptr))
def uitofp(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstUIToFP(self.ptr, ty.ptr))
def sitofp(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstSIToFP(self.ptr, ty.ptr))
def fptoui(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstFPToUI(self.ptr, ty.ptr))
def fptosi(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstFPToSI(self.ptr, ty.ptr))
def ptrtoint(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstPtrToInt(self.ptr, ty.ptr))
def inttoptr(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstIntToPtr(self.ptr, ty.ptr))
def bitcast(self, ty):
check_is_type(ty)
return Constant(_core.LLVMConstBitCast(self.ptr, ty.ptr))
def select(self, true_const, false_const):
check_is_constant(true_const)
check_is_constant(false_const)
return Constant(_core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr))
def extract_element(self, index): # note: self must be a _vector_ constant
check_is_constant(index)
return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr))
def insert_element(self, value, index): # note: self must be a _vector_ constant
check_is_constant(value)
check_is_constant(index)
return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr))
def shuffle_vector(self, vector_b, mask): # note: self must be a _vector_ constant
check_is_constant(vector_b) # note: vector_b must be a _vector_ constant
check_is_constant(mask)
return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr))
class GlobalValue(Constant):
def __init__(self, ptr, module):
Constant.__init__(self, ptr)
self._module = module # hang on to the module
def _delete(self):
self._module = None # set it free
self.ptr = None
def get_linkage(self): return _core.LLVMGetLinkage(self.ptr)
def set_linkage(self, value): _core.LLVMSetLinkage(self.ptr, value)
linkage = property(get_linkage, set_linkage)
def get_section(self): return _core.LLVMGetSection(self.ptr)
def set_section(self, value): return _core.LLVMSetSection(self.ptr, value)
section = property(get_section, set_section)
def get_visibility(self): return _core.LLVMGetVisibility(self.ptr)
def set_visibility(self, value): return _core.LLVMSetVisibility(self.ptr, value)
visibility = property(get_visibility, set_visibility)
def get_alignment(self): return _core.LLVMGetAlignment(self.ptr)
def set_alignment(self, value): return _core.LLVMSetAlignment(self.ptr, value)
alignment = property(get_alignment, set_alignment)
@property
def is_declaration(self):
return _core.LLVMIsDeclaration(self.ptr) != 0
@property
def module(self):
return self._module
class GlobalVariable(GlobalValue):
@staticmethod
def new(module, ty, name):
check_is_type(ty)
return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name), module)
@staticmethod
def get(module, name):
return GlobalVariable(_core.LLVMGetNamedGlobal(module.ptr, name), module)
def __init__(self, ptr, module):
GlobalValue.__init__(self, ptr, module)
def delete(self):
_core.LLVMDeleteGlobal(self.ptr)
self._delete()
def get_initializer(self):
if _core.LLVMHasInitializer(self.ptr):
return Constant(_core.LLVMGetInitializer(self.ptr))
else:
return None
def set_initializer(self, const):
check_is_constant(const)
_core.LLVMSetInitializer(self.ptr, const.ptr)
initializer = property(get_initializer, set_initializer)
def get_is_global_constant(self):
return _core.LLVMIsGlobalConstant(self.ptr)
def set_is_global_constant(self, value):
value = 1 if value else 0
_core.LLVMSetGlobalConstant(self.ptr, value)
global_constant = property(get_is_global_constant, set_is_global_constant)
class Argument(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
def add_attribute(self, attr):
_core.LLVMAddParamAttr(self.ptr, attr)
def remove_attribute(self, attr):
_core.LLVMRemoveParamAttr(self.ptr, attr)
def set_alignment(self, align):
_core.LLVMSetParamAlignment(self.ptr, align)
class Function(GlobalValue):
@staticmethod
def new(module, func_ty, name):
return Function(_core.LLVMAddFunction(module.ptr, name, func_ty.ptr), module)
@staticmethod
def get(module, name):
return Function(_core.LLVMGetNamedFunction(module.ptr, name), module)
def __init__(self, ptr, module):
GlobalValue.__init__(self, ptr, module)
def delete(self):
_core.LLVMDeleteFunction(self.ptr)
self._delete()
@property
def intrinsic_id(self):
return _core.LLVMGetIntrinsicID(self.ptr)
def get_calling_convention(self): return _core.LLVMGetFunctionCallConv(self.ptr)
def set_calling_convention(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value)
calling_convention = property(get_calling_convention, set_calling_convention)
def get_collector(self): return _core.LLVMGetCollector(self.ptr)
def set_collector(self, value): _core.LLVMSetCollector(self.ptr, value)
collector = property(get_collector, set_collector)
@property
def args(self):
return wrapiter(_core.LLVMGetFirstParam, _core.LLVMGetNextParam,
self.ptr, Argument)
@property
def basic_block_count(self):
return _core.LLVMCountBasicBlocks(self.ptr)
def get_entry_basic_block(self):
if self.basic_block_count == 0:
return None
return BasicBlock(_core.LLVMGetEntryBasicBlock(self.ptr))
def append_basic_block(self, name):
return BasicBlock(_core.LLVMAppendBasicBlock(self.ptr, name))
@property
def basic_blocks(self):
return wrapiter(_core.LLVMGetFirstBasicBlock,
_core.LLVMGetNextBasicBlock, self.ptr, BasicBlock)
def verify(self):
# Although we're just asking LLVM to return the success or
# failure, it appears to print result to stderr and abort.
return _core.LLVMVerifyFunction(self.ptr) != 0
#===----------------------------------------------------------------------===
# Instruction
#===----------------------------------------------------------------------===
class Instruction(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
@property
def basic_block(self):
return BasicBlock(_core.LLVMGetInstructionParent(self.ptr))
class CallOrInvokeInstruction(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
def get_calling_convention(self): return _core.LLVMGetInstructionCallConv(self.ptr)
def set_calling_convention(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value)
calling_convention = property(get_calling_convention, set_calling_convention)
def add_parameter_attribute(self, idx, attr):
_core.LLVMAddInstrParamAttr(self.ptr, idx, attr)
def remove_parameter_attribute(self, idx, attr):
_core.LLVMRemoveInstrParamAttr(self.ptr, idx, attr)
def set_parameter_alignment(self, idx, align):
_core.LLVMSetInstrParamAlignment(self.ptr, idx, align)
class PHINode(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
@property
def incoming_count(self):
return _core.LLVMCountIncoming(self.ptr)
def add_incoming(self, value, block):
check_is_value(value)
check_is_basic_block(block)
_core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr)
def get_incoming_value(self, idx):
return Value(_core.LLVMGetIncomingValue(self.ptr, idx))
def get_incoming_block(self, idx):
return BasicBlock(_core.LLVMGetIncomingBlock(self.ptr, idx))
class SwitchInstruction(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
def add_case(self, const, bblk):
check_is_constant(const) # and has to be an int too
check_is_basic_block(bblk)
_core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr)
#===----------------------------------------------------------------------===
# Basic block
#===----------------------------------------------------------------------===
class BasicBlock(Value):
def __init__(self, ptr):
self.ptr = ptr
def insert_before(self, name):
return BasicBlock(_core.LLVMInsertBasicBlock(self.ptr, name))
def delete(self):
_core.LLVMDeleteBasicBlock(self.ptr)
self.ptr = None
@property
def function(self):
return Function(_core.LLVMGetBasicBlockParent(self.ptr))
@property
def instructions(self):
return wrapiter(_core.LLVMGetFirstInstruction,
_core.LLVMGetNextInstruction, self.ptr, Instruction)
#===----------------------------------------------------------------------===
# Builder
#===----------------------------------------------------------------------===
class Builder(object):
@staticmethod
def new(basic_block):
check_is_basic_block(basic_block)
b = Builder(_core.LLVMCreateBuilder())
b.position_at_end(basic_block)
return b
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeBuilder(self.ptr)
def position_at_beginning(self, bblk):
"""Position the builder at the beginning of the given block.
Next instruction inserted will be first one in the block."""
# Avoids using "blk.instructions", which will fetch all the
# instructions into a list. Don't try this at home, though.
first_inst = Instruction(_core.LLVMGetFirstInstruction(self.block.ptr))
self.position_before(first_inst)
def position_at_end(self, bblk):
"""Position the builder at the end of the given block.
Next instruction inserted will be last one in the block."""
_core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr)
def position_before(self, instr):
"""Position the builder before the given instruction.
The instruction can belong to a basic block other than the
current one."""
_core.LLVMPositionBuilderBefore(self.ptr, instr.ptr)
@property
def block(self):
return BasicBlock(_core.LLVMGetInsertBlock(self.ptr))
# terminator instructions
def ret_void(self):
return Instruction(_core.LLVMBuildRetVoid(self.ptr))
def ret(self, value):
check_is_value(value)
return Instruction(_core.LLVMBuildRet(self.ptr, value.ptr))
def ret_many(self, values):
vs = unpack_values(values)
return Instruction(_core.LLVMBuildRetMultiple(self.ptr, vs))
def branch(self, bblk):
check_is_basic_block(bblk)
return Instruction(_core.LLVMBuildBr(self.ptr, bblk.ptr))
def cbranch(self, if_value, then_blk, else_blk):
check_is_value(if_value)
check_is_basic_block(then_blk)
check_is_basic_block(else_blk)
return Instruction(_core.LLVMBuildCondBr(self.ptr, if_value.ptr, then_blk.ptr, else_blk.ptr))
def switch(self, value, else_blk, n=10):
check_is_value(value) # value has to be of any 'int' type
check_is_basic_block(else_blk)
return SwitchInstruction(_core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n))
def invoke(self, func, args, then_blk, catch_blk, name=""):
check_is_function(func)
check_is_basic_block(then_blk)
check_is_basic_block(catch_blk)
args2 = unpack_values(args)
return CallOrInvokeInstruction(_core.LLVMBuildInvoke(self.ptr, func.ptr, args2, then_blk.ptr, catch_blk.ptr, name))
def unwind(self):
return Instruction(_core.LLVMBuildUnwind(self.ptr))
def unreachable(self):
return Instruction(_core.LLVMBuildUnreachable(self.ptr))
# arithmethic, bitwise and logical
def add(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name))
def sub(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name))
def mul(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name))
def udiv(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def sdiv(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def fdiv(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name))
def urem(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name))
def srem(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name))
def frem(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name))
def shl(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name))
def lshr(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name))
def ashr(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name))
def and_(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name))
def or_(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name))
def xor(self, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name))
def neg(self, val, name=""):
check_is_value(val)
return Instruction(_core.LLVMBuildNeg(self.ptr, val.ptr, name))
def not_(self, val, name=""):
check_is_value(val)
return Instruction(_core.LLVMBuildNot(self.ptr, val.ptr, name))
# memory
def malloc(self, ty, name=""):
check_is_type(ty)
return Instruction(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name))
def malloc_array(self, ty, size, name=""):
check_is_type(ty)
check_is_value(size)
return Instruction(_core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name))
def alloca(self, ty, name=""):
check_is_type(ty)
return Instruction(_core.LLVMBuildAlloca(self.ptr, ty.ptr, name))
def alloca_array(self, ty, size, name=""):
check_is_type(ty)
check_is_value(size)
return Instruction(_core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name))
def free(self, ptr):
check_is_value(ptr)
return Instruction(_core.LLVMBuildFree(self.ptr, ptr.ptr))
def load(self, ptr, name=""):
check_is_value(ptr)
return Instruction(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name))
def store(self, value, ptr):
check_is_value(value)
check_is_value(ptr)
return Instruction(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr))
def gep(self, ptr, indices, name=""):
check_is_value(ptr)
index_ptrs = unpack_values(indices)
return Value(_core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name))
# casts and extensions
def trunc(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name))
def zext(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name))
def sext(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name))
def fptoui(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name))
def fptosi(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name))
def uitofp(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name))
def sitofp(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name))
def fptrunc(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name))
def fpext(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name))
def ptrtoint(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name))
def inttoptr(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name))
def bitcast(self, value, dest_ty, name=""):
check_is_value(value)
check_is_type(dest_ty)
return Value(_core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name))
# comparisons
def icmp(self, ipred, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name))
def fcmp(self, rpred, lhs, rhs, name=""):
check_is_value(lhs)
check_is_value(rhs)
return Value(_core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name))
# after LLVM 2.3!
# def vicmp(self, ipred, lhs, rhs, name=""):
# check_is_value(lhs)
# check_is_value(rhs)
# return Value(_core.LLVMBuildVICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name))
#
# def vfcmp(self, rpred, lhs, rhs, name=""):
# check_is_value(lhs)
# check_is_value(rhs)
# return Value(_core.LLVMBuildVFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name))
# misc
def getresult(self, retval, idx, name=""):
check_is_value(retval)
return PHINode(_core.LLVMBuildGetResult(self.ptr, retval.ptr, idx, name))
def phi(self, ty, name=""):
check_is_type(ty)
return PHINode(_core.LLVMBuildPhi(self.ptr, ty.ptr, name))
def call(self, fn, args, name=""):
check_is_function(fn)
arg_ptrs = unpack_values(args)
return CallOrInvokeInstruction(_core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name))
def select(self, cond, then_blk, else_blk, name=""):
check_is_value(cond)
check_is_basic_block(then_blk)
check_is_basic_block(else_blk)
return Value(_core.LLVMBuildSelect(self.ptr, cond.ptr, then_blk.ptr, else_blk.ptr, name))
def vaarg(self, list_val, ty, name=""):
check_is_value(list_val)
check_is_type(ty)
return Instruction(_core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name))
def extract_element(self, vec_val, idx_val, name=""):
check_is_value(vec_val)
check_is_value(idx_val)
return Value(_core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, idx_val.ptr, name))
def insert_element(self, vec_val, elt_val, idx_val, name=""):
check_is_value(vec_val)
check_is_value(elt_val)
check_is_value(idx_val)
return Value(_core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, elt_val.ptr, idx_val.ptr, name))
def shuffle_vector(self, vecA, vecB, mask, name=""):
check_is_value(vecA)
check_is_value(vecB)
check_is_value(mask)
return Value(_core.LLVMBuildShuffleVector(self.ptr, vecA.ptr, vecB.ptr, mask.ptr, name))
#===----------------------------------------------------------------------===
# Module provider
#===----------------------------------------------------------------------===
class ModuleProvider(llvm.Ownable):
@staticmethod
def new(module):
check_is_module(module)
check_is_unowned(module)
return ModuleProvider(
_core.LLVMCreateModuleProviderForExistingModule(module.ptr),
module)
def __init__(self, ptr, module):
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)
#===----------------------------------------------------------------------===
# Memory buffer
#===----------------------------------------------------------------------===
class MemoryBuffer(object):
@staticmethod
def from_file(self, fname):
ret = _core.LLVMCreateMemoryBufferWithContentsOfFile(fname)
if isinstance(ret, str):
return (None, ret)
else:
obj = MemoryBuffer(ret)
return (obj, "")
@staticmethod
def from_stdin(self):
ret = _core.LLVMCreateMemoryBufferWithSTDIN()
if isinstance(ret, str):
return (None, ret)
else:
obj = MemoryBuffer(ret)
return (obj, "")
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeMemoryBuffer(self.ptr)