llvmpy/llvm/core.py
2008-06-09 17:39:17 +00:00

1363 lines
41 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 __del__(self):
llvm.Ownable.__del__(self)
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)
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)
def verify(self):
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:
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 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 struct() method."""
elems = unpack_types(element_tys)
return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT)
@staticmethod
def array(element_ty, count):
check_is_type(element_ty)
return _make_type(_core.LLVMArrayType(element_ty.ptr, count), TYPE_ARRAY)
@staticmethod
def pointer(pointee_ty, addr_space=0):
check_is_type(pointee_ty)
return _make_type(_core.LLVMPointerType(pointee_ty.ptr, addr_space), TYPE_POINTER)
@staticmethod
def vector(element_ty, count):
check_is_type(element_ty)
return _make_type(_core.LLVMVectorType(element_ty.ptr, count), TYPE_VECTOR)
@staticmethod
def void():
return _make_type(_core.LLVMVoidType(), TYPE_VOID)
@staticmethod
def label():
return _make_type(_core.LLVMLabelType(), TYPE_LABEL)
@staticmethod
def opaque():
return _make_type(_core.LLVMOpaqueType(), TYPE_OPAQUE)
def __init__(self, ptr, kind):
self.ptr = ptr
self.kind = kind
def __str__(self):
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 to a concrete class.
This object is no longer valid after refining, so do not hold references
to it after calling."""
check_is_type(dest)
_core.LLVMRefineType(self.ptr, dest.ptr)
self.ptr = None
class IntegerType(Type):
def __init__(self, ptr, kind):
Type.__init__(self, ptr, kind)
@property
def width(self):
return _core.LLVMGetIntTypeWidth(self.ptr)
class FunctionType(Type):
def __init__(self, ptr, kind):
Type.__init__(self, ptr, kind)
@property
def return_type(self):
ptr = _core.LLVMGetReturnType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def vararg(self):
return _core.LLVMIsFunctionVarArg(self.ptr) != 0
@property
def args(self):
pp = _core.LLVMGetFunctionTypeParams(self.ptr)
return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ]
@property
def arg_count(self):
return _core.LLVMCountParamTypes(self.ptr)
class StructType(Type):
def __init__(self, ptr, kind):
Type.__init__(self, ptr, kind)
@property
def element_count(self):
return _core.LLVMCountStructElementTypes(self.ptr)
@property
def element_types(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):
Type.__init__(self, ptr, kind)
@property
def element_type(self):
ptr = _core.LLVMGetElementType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def element_count(self):
return _core.LLVMGetArrayLength(self.ptr)
class PointerType(Type):
def __init__(self, ptr, kind):
Type.__init__(self, ptr, kind)
@property
def address_space(self):
return _core.LLVMGetPointerAddressSpace(self.ptr)
class VectorType(Type):
def __init__(self, ptr, kind):
Type.__init__(self, ptr, kind)
@property
def element_type(self):
ptr = _core.LLVMGetElementType(self.ptr)
kind = _core.LLVMGetTypeKind(ptr)
return _make_type(ptr, kind)
@property
def element_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(consts, 0))
@staticmethod
def packed_struct(consts):
const_ptrs = unpack_constants(consts)
return Constant(_core.LLVMConstStruct(consts, 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 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(self.ptr, int_pred, rhs.ptr))
def fcmp(self, real_pred, rhs):
check_is_constant(rhs)
return Constant(_core.LLVMConstFCmp(self.ptr, real_pred, 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(self, index): # note: self must be a _vector_ constant
check_is_constant(index)
return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr))
def insert(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(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):
Constant.__init__(self, ptr)
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)
@property
def module(self):
mod = Module(_core.LLVMGetGlobalParent(self.ptr))
owner = dummy_owner(mod)
return mod
class GlobalVariable(GlobalValue):
@staticmethod
def new(module, ty, name):
check_is_type(ty)
return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name))
@staticmethod
def get(module, name):
return GlobalVariable(_core.LLVMGetNamedGlobal(module.ptr, name))
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self):
_core.LLVMDeleteGlobal(self.ptr)
self.ptr = None
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)
@property
def function(self):
return Function(_core.LLVMGetParamParent(self.ptr))
class Function(GlobalValue):
@staticmethod
def new(module, func_ty, name):
return Function(_core.LLVMAddFunction(module.ptr, name, func_ty.ptr))
@staticmethod
def get(module, name):
return Function(_core.LLVMGetNamedFunction(module.ptr, name))
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self):
_core.LLVMDeleteFunction(self.ptr)
self.ptr = None
@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):
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):
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.LLVMGetFunctionCallConv(self.ptr)
def set_calling_convention(self, value): _core.LLVMSetFunctionCallConv(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():
return Builder(_core.LLVMCreateBuilder())
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeBuilder(self.ptr)
def position(self, block, instr=None):
if instr:
_core.LLVMPositionBuilder(self.ptr, block.ptr, instr.ptr)
else:
_core.LLVMPositionBuilder(self.ptr, block.ptr)
def position_before(self, instr):
_core.LLVMPositionBuilderBefore(self.ptr, instr.ptr)
def position_at_end(self, bblk):
_core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr)
@property
def insert_block(self):
return BasicBlock(_core.LLVMGetInsertBlock(self.ptr))
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 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-related
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
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))
# misc
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, if_blk, then_blk, else_blk, name=""):
check_is_basic_block(if_blk)
check_is_basic_block(then_blk)
check_is_basic_block(else_blk)
return Value(_core.LLVMBuildSelect(self.ptr, if_blk.ptr, then_blk.ptr, else_blk.ptr, name))
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)
def __del__(self):
llvm.Ownable.__del__(self)
#===----------------------------------------------------------------------===
# 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)