Removed cyclic dependency _util <-> core. Added testcases. Passes in _core.c. Code cleanup.

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@32 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2008-08-11 17:11:57 +00:00
commit 4ee007190c
7 changed files with 293 additions and 92 deletions

View file

@ -10,7 +10,7 @@ VERSION = '0.3'
#===----------------------------------------------------------------------===
class LLVMException(Exception):
"""Generic LLVM exception."""
"""Generic LLVM exception."""
def __init__(self, msg=""):
Exception.__init__(self, msg)
@ -21,13 +21,13 @@ class LLVMException(Exception):
#===----------------------------------------------------------------------===
class Ownable(object):
"""Objects that can be owned.
"""Objects that can be owned.
Modules and Module Providers can be owned, i.e., the responsibility of
Modules and Module Providers can be owned, i.e., the responsibility of
destruction of ownable objects can be handed over to other objects. The
llvm.Ownable class represents objects that can be so owned. This class
is NOT intended for public use.
"""
llvm.Ownable class represents objects that can be so owned. This class
is NOT intended for public use.
"""
def __init__(self, ptr, del_fn):
self.ptr = ptr

View file

@ -657,14 +657,72 @@ _wrap_obj2none(LLVMDisposePassManager, LLVMPassManagerRef)
/* Passes */
/*===----------------------------------------------------------------------===*/
_wrap_obj2none(LLVMAddConstantPropagationPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddInstructionCombiningPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddPromoteMemoryToRegisterPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddDemoteMemoryToRegisterPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddReassociatePass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddGVNPass, LLVMPassManagerRef)
_wrap_obj2none(LLVMAddCFGSimplificationPass, LLVMPassManagerRef)
#define _wrap_pass(P) \
_wrap_obj2none( LLVMAdd ## P ## Pass, LLVMPassManagerRef)
_wrap_pass( AggressiveDCE )
_wrap_pass( ArgumentPromotion )
_wrap_pass( BlockPlacement )
_wrap_pass( BreakCriticalEdges )
_wrap_pass( CodeGenPrepare )
_wrap_pass( CondPropagation )
_wrap_pass( ConstantMerge )
_wrap_pass( ConstantPropagation )
_wrap_pass( DeadCodeElimination )
_wrap_pass( DeadArgElimination )
_wrap_pass( DeadTypeElimination )
_wrap_pass( DeadInstElimination )
_wrap_pass( DeadStoreElimination )
_wrap_pass( GCSE )
_wrap_pass( GlobalDCE )
_wrap_pass( GlobalOptimizer )
_wrap_pass( GVN )
_wrap_pass( GVNPRE )
_wrap_pass( IndMemRem )
_wrap_pass( IndVarSimplify )
_wrap_pass( FunctionInlining )
_wrap_pass( BlockProfiler )
_wrap_pass( EdgeProfiler )
_wrap_pass( FunctionProfiler )
_wrap_pass( NullProfilerRS )
_wrap_pass( RSProfiling )
_wrap_pass( InstructionCombining )
_wrap_pass( Internalize )
_wrap_pass( IPConstantPropagation )
_wrap_pass( IPSCCP )
_wrap_pass( JumpThreading )
_wrap_pass( LCSSA )
_wrap_pass( LICM )
_wrap_pass( LoopDeletion )
_wrap_pass( LoopExtractor )
_wrap_pass( SingleLoopExtractor )
_wrap_pass( LoopIndexSplit )
_wrap_pass( LoopStrengthReduce )
_wrap_pass( LoopRotate )
_wrap_pass( LoopUnroll )
_wrap_pass( LoopUnswitch )
_wrap_pass( LoopSimplify )
_wrap_pass( LowerAllocations )
_wrap_pass( LowerInvoke )
_wrap_pass( LowerSetJmp )
_wrap_pass( LowerSwitch )
_wrap_pass( PromoteMemoryToRegister )
_wrap_pass( MemCpyOpt )
_wrap_pass( UnifyFunctionExitNodes )
_wrap_pass( PredicateSimplifier )
_wrap_pass( PruneEH )
_wrap_pass( RaiseAllocations )
_wrap_pass( Reassociate )
_wrap_pass( DemoteRegisterToMemory )
_wrap_pass( ScalarReplAggregates )
_wrap_pass( SCCP )
_wrap_pass( SimplifyLibCalls )
_wrap_pass( CFGSimplification )
_wrap_pass( StripSymbols )
_wrap_pass( StripDeadPrototypes )
_wrap_pass( StructRetPromotion )
_wrap_pass( TailCallElimination )
_wrap_pass( TailDuplication )
/*===----------------------------------------------------------------------===*/
/* Target Data */
@ -836,6 +894,7 @@ _wrap_objintlist2obj(LLVMGetIntrinsic, LLVMModuleRef, LLVMTypeRef,
/*===----------------------------------------------------------------------===*/
#define _method( func ) { # func , _w ## func , METH_VARARGS },
#define _pass( P ) _method( LLVMAdd ## P ## Pass )
static PyMethodDef core_methods[] = {
@ -1165,13 +1224,69 @@ static PyMethodDef core_methods[] = {
_method( LLVMDisposePassManager )
/* Passes */
_method( LLVMAddConstantPropagationPass )
_method( LLVMAddInstructionCombiningPass )
_method( LLVMAddPromoteMemoryToRegisterPass )
_method( LLVMAddDemoteMemoryToRegisterPass )
_method( LLVMAddReassociatePass )
_method( LLVMAddGVNPass )
_method( LLVMAddCFGSimplificationPass )
_pass( AggressiveDCE )
_pass( ArgumentPromotion )
_pass( BlockPlacement )
_pass( BreakCriticalEdges )
_pass( CodeGenPrepare )
_pass( CondPropagation )
_pass( ConstantMerge )
_pass( ConstantPropagation )
_pass( DeadCodeElimination )
_pass( DeadArgElimination )
_pass( DeadTypeElimination )
_pass( DeadInstElimination )
_pass( DeadStoreElimination )
_pass( GCSE )
_pass( GlobalDCE )
_pass( GlobalOptimizer )
_pass( GVN )
_pass( GVNPRE )
_pass( IndMemRem )
_pass( IndVarSimplify )
_pass( FunctionInlining )
_pass( BlockProfiler )
_pass( EdgeProfiler )
_pass( FunctionProfiler )
_pass( NullProfilerRS )
_pass( RSProfiling )
_pass( InstructionCombining )
_pass( Internalize )
_pass( IPConstantPropagation )
_pass( IPSCCP )
_pass( JumpThreading )
_pass( LCSSA )
_pass( LICM )
_pass( LoopDeletion )
_pass( LoopExtractor )
_pass( SingleLoopExtractor )
_pass( LoopIndexSplit )
_pass( LoopStrengthReduce )
_pass( LoopRotate )
_pass( LoopUnroll )
_pass( LoopUnswitch )
_pass( LoopSimplify )
_pass( LowerAllocations )
_pass( LowerInvoke )
_pass( LowerSetJmp )
_pass( LowerSwitch )
_pass( PromoteMemoryToRegister )
_pass( MemCpyOpt )
_pass( UnifyFunctionExitNodes )
_pass( PredicateSimplifier )
_pass( PruneEH )
_pass( RaiseAllocations )
_pass( Reassociate )
_pass( DemoteRegisterToMemory )
_pass( ScalarReplAggregates )
_pass( SCCP )
_pass( SimplifyLibCalls )
_pass( CFGSimplification )
_pass( StripSymbols )
_pass( StripDeadPrototypes )
_pass( StructRetPromotion )
_pass( TailCallElimination )
_pass( TailDuplication )
/* Target Data */
_method( LLVMCreateTargetData )

View file

@ -2,7 +2,6 @@
Used only in other modules, not for public use."""
import llvm.core as core
import llvm
@ -17,15 +16,6 @@ def check_gen(obj, type):
msg = "argument not an instance of llvm.core.%s" % type_str
raise TypeError, msg
def check_is_type(obj): check_gen(obj, core.Type)
def check_is_value(obj): check_gen(obj, core.Value)
def check_is_pointer(obj): check_gen(obj, core.Pointer)
def check_is_constant(obj): check_gen(obj, core.Constant)
def check_is_function(obj): check_gen(obj, core.Function)
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_unowned(ownable):
if ownable.owner:
raise llvm.LLVMException, "object is already owned"
@ -41,10 +31,6 @@ 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)
#===----------------------------------------------------------------------===
# Helper to wrap over iterables (LLVMFirstXXX, LLVMNextXXX). This used

View file

@ -13,7 +13,6 @@ from llvm._util import * # utility functions
# Enumerations
#===----------------------------------------------------------------------===
# type kinds
TYPE_VOID = 0
TYPE_FLOAT = 1
@ -694,9 +693,26 @@ INTR_X86_SSSE3_PSIGN_W_128 = 594
#===----------------------------------------------------------------------===
# Module
# Helpers (for internal use)
#===----------------------------------------------------------------------===
def check_is_type(obj): check_gen(obj, Type)
def check_is_value(obj): check_gen(obj, Value)
def check_is_pointer(obj): check_gen(obj, Pointer)
def check_is_constant(obj): check_gen(obj, Constant)
def check_is_function(obj): check_gen(obj, Function)
def check_is_basic_block(obj): check_gen(obj, BasicBlock)
def check_is_module(obj): check_gen(obj, Module)
def check_is_module_provider(obj): check_gen(obj, ModuleProvider)
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)
#===----------------------------------------------------------------------===
# Module
#===----------------------------------------------------------------------===
class Module(llvm.Ownable):
"""A Module instance stores all the information related to an LLVM module.
@ -865,7 +881,6 @@ class Module(llvm.Ownable):
# Types
#===----------------------------------------------------------------------===
class Type(object):
"""Represents a type, like a 32-bit integer or an 80-bit x86 float.
@ -1181,7 +1196,6 @@ def _make_type(ptr, kind):
# Type Handle
#===----------------------------------------------------------------------===
class TypeHandle(object):
@staticmethod
@ -1205,7 +1219,6 @@ class TypeHandle(object):
# Values
#===----------------------------------------------------------------------===
class Value(object):
def __init__(self, ptr):
@ -1220,13 +1233,13 @@ class Value(object):
else:
return False
def get_name(self):
def _get_name(self):
return _core.LLVMGetValueName(self.ptr)
def set_name(self, value):
def _set_name(self, value):
return _core.LLVMSetValueName(self.ptr, value)
name = property(get_name, set_name)
name = property(_get_name, _set_name)
@property
def type(self):
@ -1472,21 +1485,21 @@ class GlobalValue(Constant):
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_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_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_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)
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):
@ -1518,26 +1531,26 @@ class GlobalVariable(GlobalValue):
_core.LLVMDeleteGlobal(self.ptr)
self._delete()
def get_initializer(self):
def _get_initializer(self):
if _core.LLVMHasInitializer(self.ptr):
return Constant(_core.LLVMGetInitializer(self.ptr))
else:
return None
def set_initializer(self, const):
def _set_initializer(self, const):
check_is_constant(const)
_core.LLVMSetInitializer(self.ptr, const.ptr)
initializer = property(get_initializer, set_initializer)
initializer = property(_get_initializer, _set_initializer)
def get_is_global_constant(self):
def _get_is_global_constant(self):
return _core.LLVMIsGlobalConstant(self.ptr)
def set_is_global_constant(self, value):
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)
global_constant = property(_get_is_global_constant, _set_is_global_constant)
class Argument(Value):
@ -1587,13 +1600,13 @@ class Function(GlobalValue):
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_cc(self): return _core.LLVMGetFunctionCallConv(self.ptr)
def _set_cc(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value)
calling_convention = property(_get_cc, _set_cc)
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)
def _get_coll(self): return _core.LLVMGetCollector(self.ptr)
def _set_coll(self, value): _core.LLVMSetCollector(self.ptr, value)
collector = property(_get_coll, _set_coll)
@property
def args(self):
@ -1642,9 +1655,9 @@ 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 _get_cc(self): return _core.LLVMGetInstructionCallConv(self.ptr)
def _set_cc(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value)
calling_convention = property(_get_cc, _set_cc)
def add_parameter_attribute(self, idx, attr):
_core.LLVMAddInstrParamAttr(self.ptr, idx, attr)
@ -1692,7 +1705,6 @@ class SwitchInstruction(Instruction):
# Basic block
#===----------------------------------------------------------------------===
class BasicBlock(Value):
def __init__(self, ptr):
@ -1705,9 +1717,10 @@ class BasicBlock(Value):
_core.LLVMDeleteBasicBlock(self.ptr)
self.ptr = None
@property
def function(self):
return Function(_core.LLVMGetBasicBlockParent(self.ptr))
#-- disabled till we find a proper way to do it --
#@property
#def function(self):
# return Function(_core.LLVMGetBasicBlockParent(self.ptr))
@property
def instructions(self):
@ -1719,7 +1732,6 @@ class BasicBlock(Value):
# Builder
#===----------------------------------------------------------------------===
class Builder(object):
@staticmethod
@ -2058,7 +2070,6 @@ class Builder(object):
# Module provider
#===----------------------------------------------------------------------===
class ModuleProvider(llvm.Ownable):
@staticmethod
@ -2080,7 +2091,6 @@ class ModuleProvider(llvm.Ownable):
# Memory buffer
#===----------------------------------------------------------------------===
class MemoryBuffer(object):
@staticmethod

View file

@ -33,19 +33,19 @@ class GenericValue(object):
@staticmethod
def int(ty, intval):
check_is_type(ty)
core.check_is_type(ty)
ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 0)
return GenericValue(ptr)
@staticmethod
def int_signed(ty, intval):
check_is_type(ty)
core.check_is_type(ty)
ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 1)
return GenericValue(ptr)
@staticmethod
def real(ty, floatval):
check_is_type(ty) # only float or double
core.check_is_type(ty) # only float or double
ptr = _core.LLVMCreateGenericValueOfFloat(ty.ptr, floatval)
return GenericValue(ptr)
@ -62,14 +62,14 @@ class GenericValue(object):
return _core.LLVMGenericValueToInt(self.ptr, 1)
def as_real(self, ty):
check_is_type(ty) # only float or double
core.check_is_type(ty) # only float or double
return _core.LLVMGenericValueToFloat(ty.ptr, self.ptr)
# helper functions for generic value objects
def _check_is_generic_value(obj): check_gen(obj, GenericValue)
def check_is_generic_value(obj): check_gen(obj, GenericValue)
def _unpack_generic_values(objlist):
return unpack_gen(objlist, _check_is_generic_value)
return unpack_gen(objlist, check_is_generic_value)
#===----------------------------------------------------------------------===
@ -80,8 +80,8 @@ class ExecutionEngine(object):
@staticmethod
def new(mp, force_interpreter=False):
check_is_module_provider(mp)
check_is_unowned(mp)
core.check_is_module_provider(mp)
core.check_is_unowned(mp)
ret = _core.LLVMCreateExecutionEngine(mp.ptr, int(force_interpreter))
if isinstance(ret, str):
raise llvm.LLVMException, ret
@ -95,7 +95,7 @@ class ExecutionEngine(object):
_core.LLVMDisposeExecutionEngine(self.ptr)
def run_function(self, fn, args):
check_is_function(fn)
core.check_is_function(fn)
ptrs = _unpack_generic_values(args)
gvptr = _core.LLVMRunFunction2(self.ptr, fn.ptr, ptrs)
return GenericValue(gvptr)
@ -107,11 +107,12 @@ class ExecutionEngine(object):
_core.LLVMRunStaticDestructors(self.ptr)
def free_machine_code_for(self, fn):
check_is_function(fn)
core.check_is_function(fn)
_core.LLVMFreeMachineCodeForFunction(self.ptr, fn.ptr)
# CRASH! BOOM!! BANG!!! TODO FIXME
def add_module_provider(self, mp):
check_is_module_provider(mp)
core.check_is_module_provider(mp)
_core.LLVMAddModuleProvider(self.ptr, mp.ptr)
@property

View file

@ -50,7 +50,8 @@ def call_setup(llvm_config):
ldflags = _run(llvm_config + ' --ldflags')
libs_core, objs_core = get_libs_and_objs(llvm_config,
['core', 'analysis', 'scalaropts', 'executionengine',
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter'])
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
'instrumentation', 'ipa', 'ipo', 'transformutils'])
std_libs = [ 'pthread', 'm' ]
if not sys.platform.startswith("openbsd"):

View file

@ -8,9 +8,30 @@
from llvm import *
from llvm.core import *
from llvm.ee import *
ti = Type.int()
def do_llvmexception():
print " Testing class LLVMException"
e = LLVMException()
def do_ownable():
print " Testing class Ownable"
o = Ownable(None, lambda x: None)
try:
o._own(None)
o._disown()
except LLVMException:
pass
def do_llvm():
print " Testing module llvm"
do_llvmexception()
do_ownable()
def do_module():
print " Testing class Module"
m = Module.new('test')
@ -134,7 +155,7 @@ def do_constant():
k = Constant.int(ti, 10)
f = Constant.real(Type.float(), 3.1415)
k.neg().not_().add(k).sub(k).mul(k).udiv(k).sdiv(k).urem(k)
k.srem(k).and_(k).or_(k).icmp(IPRED_ULT, k)
k.srem(k).and_(k).or_(k).xor(k).icmp(IPRED_ULT, k)
f.fdiv(f).frem(f).fcmp(RPRED_ULT, f)
vi = Constant.vector([Constant.int(ti,42)]*10)
vf = Constant.vector([Constant.real(Type.float(), 3.14)]*10)
@ -168,7 +189,6 @@ def do_global_value():
gv = GlobalVariable.new(m, Type.int(), 'b')
s = gv.is_declaration
m = gv.module
s = gv.is_declaration
gv.linkage = LINKAGE_EXTERNAL
s = gv.linkage
gv.section = '.text'
@ -214,6 +234,7 @@ def do_function():
f.delete()
ft = Type.function(ti, [ti]*20)
f = Function.new(m, ft, 'func2')
f2 = Function.intrinsic(m, INTR_COS, [ti])
g = f.intrinsic_id
f.calling_convenion = CC_FASTCALL
g = f.calling_convenion
@ -286,6 +307,22 @@ def do_switchinstruction():
s.add_case(Constant.int(ti, 10), b)
def do_basicblock():
print " Testing class BasicBlock"
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
b = f.append_basic_block('b')
bb = Builder.new(b)
s = bb.switch(f.args[0], b)
s.add_case(Constant.int(ti, 10), b)
s = list(b.instructions)
b2 = b.insert_before('before')
b2.delete()
# ff = b.function
# ^ not working yet!
def do_builder():
print " Testing class Builder"
m = Module.new('a')
@ -387,14 +424,65 @@ def do_llvm_core():
do_callorinvokeinstruction()
do_phinode()
do_switchinstruction()
do_basicblock()
do_builder()
do_moduleprovider()
def do_llvm():
def do_targetdata():
print " Testing class TargetData"
t = TargetData.new('')
t = str(t)
def do_genericvalue():
print " Testing class GenericValue"
v = GenericValue.int(ti, 1)
v = GenericValue.int_signed(ti, 1)
v = GenericValue.real(Type.float(), 3.14)
a = v.as_int()
a = v.as_int_signed()
a = v.as_real(Type.float())
def do_executionengine():
print " Testing class ExecutionEngine"
m = Module.new('a')
mp = ModuleProvider.new(m)
ee = ExecutionEngine.new(mp, True)
ft = Type.function(ti, [])
f = m.add_function(ft, 'func')
bb = f.append_basic_block('entry')
b = Builder.new(bb)
b.ret(Constant.int(ti, 42))
gv = ee.run_function(f, [])
is42 = gv.as_int() == 42
ee.run_static_ctors()
ee.run_static_dtors()
ee.free_machine_code_for(f)
t = ee.target_data
m2 = Module.new('b')
mp2 = ModuleProvider.new(m2)
# CRASHES!! TODO FIXME
# ee.add_module_provider(mp2)
m3 = Module.new('c')
mp3 = ModuleProvider.new(m3)
ee2 = ExecutionEngine.new(mp3, False)
def do_llvm_ee():
print " Testing module llvm.ee"
do_targetdata()
do_genericvalue()
do_executionengine()
def main():
print "Testing package llvm"
do_llvm()
do_llvm_core()
do_llvm_ee()
do_llvm()
main()