Added User class, moved operands to User, cleanup

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@69 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2009-02-25 11:04:25 +00:00
commit 8b6109d8eb
7 changed files with 144 additions and 154 deletions

View file

@ -323,6 +323,11 @@ _wrap_obj2none(LLVMDumpValue, LLVMValueRef)
_wrap_dumper(LLVMDumpValueToString, LLVMValueRef) _wrap_dumper(LLVMDumpValueToString, LLVMValueRef)
_wrap_obj2obj(LLVMValueGetID, LLVMValueRef, int) _wrap_obj2obj(LLVMValueGetID, LLVMValueRef, int)
/*===-- Users ------------------------------------------------------------===*/
_wrap_obj2obj(LLVMUserGetNumOperands, LLVMValueRef, int)
_wrap_objint2obj(LLVMUserGetOperand, LLVMValueRef, LLVMValueRef)
/*===-- Constant Values --------------------------------------------------===*/ /*===-- Constant Values --------------------------------------------------===*/
/* Operations on constants of any type */ /* Operations on constants of any type */
@ -534,8 +539,6 @@ _wrap_obj2obj(LLVMInstIsTrapping, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstIsVolatile, LLVMValueRef, int) _wrap_obj2obj(LLVMInstIsVolatile, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) _wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int)
_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) _wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef)
_wrap_obj2obj(LLVMInstGetNumOperands, LLVMValueRef, int)
_wrap_objint2obj(LLVMInstGetOperand, LLVMValueRef, LLVMValueRef)
/*===-- Call Sites (Call or Invoke) --------------------------------------===*/ /*===-- Call Sites (Call or Invoke) --------------------------------------===*/
@ -1115,6 +1118,11 @@ static PyMethodDef core_methods[] = {
_method( LLVMDumpValueToString ) _method( LLVMDumpValueToString )
_method( LLVMValueGetID ) _method( LLVMValueGetID )
/* Users */
_method( LLVMUserGetNumOperands )
_method( LLVMUserGetOperand )
/* Constant Values */ /* Constant Values */
/* Operations on constants of any type */ /* Operations on constants of any type */
@ -1255,8 +1263,6 @@ static PyMethodDef core_methods[] = {
_method( LLVMInstIsVolatile ) _method( LLVMInstIsVolatile )
_method( LLVMInstGetOpcode ) _method( LLVMInstGetOpcode )
_method( LLVMInstGetOpcodeName ) _method( LLVMInstGetOpcodeName )
_method( LLVMInstGetNumOperands )
_method( LLVMInstGetOperand )
/* Call Sites (Call or Invoke) */ /* Call Sites (Call or Invoke) */
_method( LLVMSetInstructionCallConv ) _method( LLVMSetInstructionCallConv )

View file

@ -329,6 +329,7 @@ class Module(llvm.Ownable, llvm.Cacheable):
Use the static method `Module.new' instead. Use the static method `Module.new' instead.
""" """
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule) llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule)
llvm.Cacheable.__init__(self, ptr)
def __str__(self): def __str__(self):
"""Text representation of a module. """Text representation of a module.
@ -666,12 +667,6 @@ class Type(object):
class IntegerType(Type): class IntegerType(Type):
"""Represents an integer 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 @property
def width(self): def width(self):
"""The width of the integer type, in bits.""" """The width of the integer type, in bits."""
@ -681,12 +676,6 @@ class IntegerType(Type):
class FunctionType(Type): class FunctionType(Type):
"""Represents a function 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 @property
def return_type(self): def return_type(self):
"""The type of the value returned by this function.""" """The type of the value returned by this function."""
@ -717,12 +706,6 @@ class FunctionType(Type):
class StructType(Type): class StructType(Type):
"""Represents a structure type.""" """Represents a structure 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 @property
def element_count(self): def element_count(self):
"""Number of elements (members) in the structure. """Number of elements (members) in the structure.
@ -746,12 +729,6 @@ class StructType(Type):
class ArrayType(Type): class ArrayType(Type):
"""Represents an array type.""" """Represents an array 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 @property
def element(self): def element(self):
ptr = _core.LLVMGetElementType(self.ptr) ptr = _core.LLVMGetElementType(self.ptr)
@ -765,12 +742,6 @@ class ArrayType(Type):
class PointerType(Type): 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 @property
def pointee(self): def pointee(self):
ptr = _core.LLVMGetElementType(self.ptr) ptr = _core.LLVMGetElementType(self.ptr)
@ -784,12 +755,6 @@ class PointerType(Type):
class VectorType(Type): 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 @property
def element(self): def element(self):
ptr = _core.LLVMGetElementType(self.ptr) ptr = _core.LLVMGetElementType(self.ptr)
@ -854,6 +819,7 @@ class TypeHandle(object):
class Value(llvm.Cacheable): class Value(llvm.Cacheable):
def __init__(self, ptr): def __init__(self, ptr):
llvm.Cacheable.__init__(self, ptr)
self.ptr = ptr self.ptr = ptr
def __str__(self): def __str__(self):
@ -887,7 +853,22 @@ class Value(llvm.Cacheable):
return _make_type(ptr, kind) return _make_type(ptr, kind)
class Constant(Value): class User(Value):
@property
def operand_count(self):
return _core.LLVMUserGetNumOperands(self.ptr)
@property
def operands(self):
"""Yields operands of this instruction."""
return [self._get_operand(i) for i in range(self.operand_count)]
def _get_operand(self, i):
return _make_value(_core.LLVMUserGetOperand(self.ptr, i))
class Constant(User):
@staticmethod @staticmethod
def null(ty): def null(ty):
@ -956,9 +937,6 @@ class Constant(Value):
check_is_type(ty) check_is_type(ty)
return _make_value(_core.LLVMSizeOf(ty.ptr)) return _make_value(_core.LLVMSizeOf(ty.ptr))
def __init__(self, ptr):
Value.__init__(self, ptr)
def neg(self): def neg(self):
return _make_value(_core.LLVMConstNeg(self.ptr)) return _make_value(_core.LLVMConstNeg(self.ptr))
@ -1121,51 +1099,39 @@ class Constant(Value):
class ConstantExpr(Constant): class ConstantExpr(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantAggregateZero(Constant): class ConstantAggregateZero(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantInt(Constant): class ConstantInt(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantFP(Constant): class ConstantFP(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantArray(Constant): class ConstantArray(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantStruct(Constant): class ConstantStruct(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantVector(Constant): class ConstantVector(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class ConstantPointerNull(Constant): class ConstantPointerNull(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr) class UndefValue(Constant):
pass
class GlobalValue(Constant): class GlobalValue(Constant):
@ -1228,9 +1194,6 @@ class GlobalVariable(GlobalValue):
raise llvm.LLVMException, ("no global named `%s`" % name) raise llvm.LLVMException, ("no global named `%s`" % name)
return _make_value(ptr) return _make_value(ptr)
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self): def delete(self):
self._delete() self._delete()
_core.LLVMDeleteGlobal(self.ptr) _core.LLVMDeleteGlobal(self.ptr)
@ -1262,9 +1225,6 @@ class GlobalVariable(GlobalValue):
class Argument(Value): class Argument(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
def add_attribute(self, attr): def add_attribute(self, attr):
_core.LLVMAddAttribute(self.ptr, attr) _core.LLVMAddAttribute(self.ptr, attr)
@ -1306,9 +1266,6 @@ class Function(GlobalValue):
return _make_value( return _make_value(
_core.LLVMGetIntrinsic(module.ptr, intrinsic_id, ptrs)) _core.LLVMGetIntrinsic(module.ptr, intrinsic_id, ptrs))
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self): def delete(self):
self._delete() self._delete()
_core.LLVMDeleteFunction(self.ptr) _core.LLVMDeleteFunction(self.ptr)
@ -1336,11 +1293,16 @@ class Function(GlobalValue):
def basic_block_count(self): def basic_block_count(self):
return _core.LLVMCountBasicBlocks(self.ptr) return _core.LLVMCountBasicBlocks(self.ptr)
def get_entry_basic_block(self): @property
def entry_basic_block(self):
if self.basic_block_count == 0: if self.basic_block_count == 0:
return None return None
return _make_value(_core.LLVMGetEntryBasicBlock(self.ptr)) return _make_value(_core.LLVMGetEntryBasicBlock(self.ptr))
def get_entry_basic_block(self):
"""Deprecated, use entry_basic_block property."""
return self.entry_basic_block
def append_basic_block(self, name): def append_basic_block(self, name):
return _make_value(_core.LLVMAppendBasicBlock(self.ptr, name)) return _make_value(_core.LLVMAppendBasicBlock(self.ptr, name))
@ -1365,10 +1327,7 @@ class Function(GlobalValue):
# Instruction # Instruction
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
class Instruction(Value): class Instruction(User):
def __init__(self, ptr):
Value.__init__(self, ptr)
@property @property
def basic_block(self): def basic_block(self):
@ -1423,24 +1382,9 @@ class Instruction(Value):
def opcode_name(self): def opcode_name(self):
return _core.LLVMInstGetOpcodeName(self.ptr) return _core.LLVMInstGetOpcodeName(self.ptr)
@property
def operand_count(self):
return _core.LLVMInstGetNumOperands(self.ptr)
@property
def operands(self):
"""Yields operands of this instruction."""
return [self._get_operand(i) for i in range(self.operand_count)]
def _get_operand(self, i):
return _make_value(_core.LLVMInstGetOperand(self.ptr, i))
class CallOrInvokeInstruction(Instruction): class CallOrInvokeInstruction(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
def _get_cc(self): return _core.LLVMGetInstructionCallConv(self.ptr) def _get_cc(self): return _core.LLVMGetInstructionCallConv(self.ptr)
def _set_cc(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value) def _set_cc(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value)
calling_convention = property(_get_cc, _set_cc) calling_convention = property(_get_cc, _set_cc)
@ -1457,9 +1401,6 @@ class CallOrInvokeInstruction(Instruction):
class PHINode(Instruction): class PHINode(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
@property @property
def incoming_count(self): def incoming_count(self):
return _core.LLVMCountIncoming(self.ptr) return _core.LLVMCountIncoming(self.ptr)
@ -1478,9 +1419,6 @@ class PHINode(Instruction):
class SwitchInstruction(Instruction): class SwitchInstruction(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
def add_case(self, const, bblk): def add_case(self, const, bblk):
check_is_constant(const) # and has to be an int too check_is_constant(const) # and has to be an int too
check_is_basic_block(bblk) check_is_basic_block(bblk)
@ -1493,9 +1431,6 @@ class SwitchInstruction(Instruction):
class BasicBlock(Value): class BasicBlock(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
def insert_before(self, name): def insert_before(self, name):
return _make_value(_core.LLVMInsertBasicBlock(self.ptr, name)) return _make_value(_core.LLVMInsertBasicBlock(self.ptr, name))
@ -1526,8 +1461,8 @@ __class_for_valueid = {
VALUE_FUNCTION : Function, VALUE_FUNCTION : Function,
VALUE_GLOBAL_ALIAS : GlobalValue, VALUE_GLOBAL_ALIAS : GlobalValue,
VALUE_GLOBAL_VARIABLE : GlobalVariable, VALUE_GLOBAL_VARIABLE : GlobalVariable,
VALUE_UNDEF_VALUE : UndefValue,
VALUE_CONSTANT_EXPR : ConstantExpr, VALUE_CONSTANT_EXPR : ConstantExpr,
VALUE_INLINE_ASM : Constant,
VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero, VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero,
VALUE_CONSTANT_INT : ConstantInt, VALUE_CONSTANT_INT : ConstantInt,
VALUE_CONSTANT_FP : ConstantFP, VALUE_CONSTANT_FP : ConstantFP,

View file

@ -237,21 +237,6 @@ unsigned LLVMInstGetOpcode(LLVMValueRef inst)
return instp->getOpcode(); return instp->getOpcode();
} }
unsigned LLVMInstGetNumOperands(LLVMValueRef inst)
{
llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
assert(instp);
return instp->getNumOperands();
}
LLVMValueRef LLVMInstGetOperand(LLVMValueRef inst, unsigned idx)
{
llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
assert(instp);
llvm::Value *operand = instp->getOperand(idx);
return llvm::wrap(operand);
}
/* llvm::unwrap a set of `n' wrapped objects starting at `values', /* llvm::unwrap a set of `n' wrapped objects starting at `values',
* into a vector of pointers to llvm::unwrapped objects `out'. */ * into a vector of pointers to llvm::unwrapped objects `out'. */
template <typename W, typename UW> template <typename W, typename UW>
@ -314,6 +299,21 @@ unsigned LLVMValueGetID(LLVMValueRef value)
return valuep->getValueID(); return valuep->getValueID();
} }
unsigned LLVMUserGetNumOperands(LLVMValueRef user)
{
llvm::User *userp = llvm::unwrap<llvm::User>(user);
assert(userp);
return userp->getNumOperands();
}
LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx)
{
llvm::User *userp = llvm::unwrap<llvm::User>(user);
assert(userp);
llvm::Value *operand = userp->getOperand(idx);
return llvm::wrap(operand);
}
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id, LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id,
LLVMTypeRef *types, unsigned n_types) LLVMTypeRef *types, unsigned n_types)
{ {

View file

@ -69,6 +69,12 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
/* Wraps llvm::Value::getValueID(). */ /* Wraps llvm::Value::getValueID(). */
unsigned LLVMValueGetID(LLVMValueRef value); unsigned LLVMValueGetID(LLVMValueRef value);
/* Wraps llvm:User::getNumOperands(). */
unsigned LLVMUserGetNumOperands(LLVMValueRef user);
/* Wraps llvm:User::getOperand(). */
LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx);
/* Wraps llvm::ConstantExpr::getVICmp(). */ /* Wraps llvm::ConstantExpr::getVICmp(). */
LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs, LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs,
LLVMValueRef rhs); LLVMValueRef rhs);
@ -121,12 +127,6 @@ const char *LLVMInstGetOpcodeName(LLVMValueRef inst);
/* Wraps llvm::Instruction::getOpcode(). */ /* Wraps llvm::Instruction::getOpcode(). */
unsigned LLVMInstGetOpcode(LLVMValueRef inst); unsigned LLVMInstGetOpcode(LLVMValueRef inst);
/* Wraps llvm:Instruction::getNumOperands(). */
unsigned LLVMInstGetNumOperands(LLVMValueRef inst);
/* Wraps llvm:Instruction::getOperand(). */
LLVMValueRef LLVMInstGetOperand(LLVMValueRef inst, unsigned idx);
/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with /* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with
* `out' pointing to an error message). Dispose error message after use, via * `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */ * LLVMDisposeMessage(). */

View file

@ -77,11 +77,15 @@ b3 = f1.get_entry_basic_block()
check(b1, b3) check(b1, b3)
print "Testing basic block aliasing 3 .. ", print "Testing basic block aliasing 3 .. ",
b31 = f1.entry_basic_block
check(b1, b31)
print "Testing basic block aliasing 4 .. ",
bldr = Builder.new(b1) bldr = Builder.new(b1)
b4 = bldr.basic_block b4 = bldr.basic_block
check(b1, b4) check(b1, b4)
print "Testing basic block aliasing 4 .. ", print "Testing basic block aliasing 5 .. ",
i1 = bldr.ret_void() i1 = bldr.ret_void()
b5 = i1.basic_block b5 = i1.basic_block
check(b1, b5) check(b1, b5)

View file

@ -4,40 +4,69 @@
from llvm.core import * from llvm.core import *
m = None
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
# implement a test function # implement a test function
def make_function(): test_module = """
test_module = """ define i32 @prod(i32, i32) {
define i32 @prod(i32, i32) { entry:
entry: %2 = mul i32 %0, %1
%2 = mul i32 %0, %1 ret i32 %2
ret i32 %2 }
}
define i32 @test_func(i32, i32, i32) { define i32 @test_func(i32, i32, i32) {
entry: entry:
%tmp1 = call i32 @prod(i32 %0, i32 %1) %tmp1 = call i32 @prod(i32 %0, i32 %1)
%tmp2 = add i32 %tmp1, %2 %tmp2 = add i32 %tmp1, %2
%tmp3 = add i32 %tmp2, 1 %tmp3 = add i32 %tmp2, 1
ret i32 %tmp3 ret i32 %tmp3
} }
""" """
class strstream(object): class strstream(object):
def __init__(self): pass def __init__(self): pass
def read(self): return test_module def read(self): return test_module
m = Module.from_assembly(strstream()) m = Module.from_assembly(strstream())
print "-"*60 print "-"*60
print m print m
print "-"*60 print "-"*60
print "Examining function `test_func':"
return m.get_function_named("test_func") test_func = m.get_function_named("test_func")
prod = m.get_function_named("prod")
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
# test operands
func = make_function() print
i1 = test_func.basic_blocks[0].instructions[0]
i2 = test_func.basic_blocks[0].instructions[1]
print "Testing User.operand_count ..",
if i1.operand_count == 3 and i2.operand_count == 2:
print "OK"
else:
print "FAIL"
print "Testing User.operands ..",
c1 = i1.operands[0] is prod
c2 = i1.operands[1] is test_func.args[0]
c3 = i1.operands[2] is test_func.args[1]
c4 = i2.operands[0] is i1
c5 = i2.operands[1] is test_func.args[2]
c6 = len(i1.operands) == 3
c7 = len(i2.operands) == 2
if c1 and c2 and c3 and c5 and c6 and c7:
print "OK"
else:
print "FAIL"
print
#===----------------------------------------------------------------------===
# show test_function
print "Examining test_function `test_test_func':"
idx = 1 idx = 1
for inst in func.basic_blocks[0].instructions: for inst in test_func.basic_blocks[0].instructions:
print "Instruction #%d:" % (idx,) print "Instruction #%d:" % (idx,)
print " operand_count =", inst.operand_count print " operand_count =", inst.operand_count
print " operands:" print " operands:"

View file

@ -168,6 +168,21 @@ def do_value():
i = k.value_id i = k.value_id
def do_user():
m = Module.new('a')
ft = Type.function(ti, [ti]*2)
f = Function.new(m, ft, 'func')
b = f.append_basic_block('a')
bb = Builder.new(b)
i1 = bb.add(f.args[0], f.args[1])
i2 = bb.ret(i1)
i1.operand_count == 2
i2.operand_count == 1
i1.operands[0] is f.args[0]
i1.operands[1] is f.args[1]
i2.operands[0] is i1
def do_constant(): def do_constant():
print " Testing class Constant" print " Testing class Constant"
Constant.null(ti) Constant.null(ti)
@ -475,6 +490,7 @@ def do_llvm_core():
do_type() do_type()
do_typehandle() do_typehandle()
do_value() do_value()
do_user()
do_constant() do_constant()
do_global_value() do_global_value()
do_global_variable() do_global_variable()