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

View file

@ -329,6 +329,7 @@ class Module(llvm.Ownable, llvm.Cacheable):
Use the static method `Module.new' instead.
"""
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule)
llvm.Cacheable.__init__(self, ptr)
def __str__(self):
"""Text representation of a module.
@ -666,12 +667,6 @@ class Type(object):
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."""
@ -681,12 +676,6 @@ class IntegerType(Type):
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."""
@ -717,12 +706,6 @@ class FunctionType(Type):
class StructType(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
def element_count(self):
"""Number of elements (members) in the structure.
@ -746,12 +729,6 @@ class StructType(Type):
class ArrayType(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
def element(self):
ptr = _core.LLVMGetElementType(self.ptr)
@ -765,12 +742,6 @@ class ArrayType(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
def pointee(self):
ptr = _core.LLVMGetElementType(self.ptr)
@ -784,12 +755,6 @@ class PointerType(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
def element(self):
ptr = _core.LLVMGetElementType(self.ptr)
@ -854,6 +819,7 @@ class TypeHandle(object):
class Value(llvm.Cacheable):
def __init__(self, ptr):
llvm.Cacheable.__init__(self, ptr)
self.ptr = ptr
def __str__(self):
@ -887,7 +853,22 @@ class Value(llvm.Cacheable):
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
def null(ty):
@ -956,9 +937,6 @@ class Constant(Value):
check_is_type(ty)
return _make_value(_core.LLVMSizeOf(ty.ptr))
def __init__(self, ptr):
Value.__init__(self, ptr)
def neg(self):
return _make_value(_core.LLVMConstNeg(self.ptr))
@ -1121,51 +1099,39 @@ class Constant(Value):
class ConstantExpr(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantAggregateZero(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantInt(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantFP(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantArray(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantStruct(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantVector(Constant):
def __init__(self, ptr):
Constant.__init__(self, ptr)
pass
class ConstantPointerNull(Constant):
pass
def __init__(self, ptr):
Constant.__init__(self, ptr)
class UndefValue(Constant):
pass
class GlobalValue(Constant):
@ -1228,9 +1194,6 @@ class GlobalVariable(GlobalValue):
raise llvm.LLVMException, ("no global named `%s`" % name)
return _make_value(ptr)
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self):
self._delete()
_core.LLVMDeleteGlobal(self.ptr)
@ -1262,9 +1225,6 @@ class GlobalVariable(GlobalValue):
class Argument(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
def add_attribute(self, attr):
_core.LLVMAddAttribute(self.ptr, attr)
@ -1306,9 +1266,6 @@ class Function(GlobalValue):
return _make_value(
_core.LLVMGetIntrinsic(module.ptr, intrinsic_id, ptrs))
def __init__(self, ptr):
GlobalValue.__init__(self, ptr)
def delete(self):
self._delete()
_core.LLVMDeleteFunction(self.ptr)
@ -1336,11 +1293,16 @@ class Function(GlobalValue):
def basic_block_count(self):
return _core.LLVMCountBasicBlocks(self.ptr)
def get_entry_basic_block(self):
@property
def entry_basic_block(self):
if self.basic_block_count == 0:
return None
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):
return _make_value(_core.LLVMAppendBasicBlock(self.ptr, name))
@ -1365,10 +1327,7 @@ class Function(GlobalValue):
# Instruction
#===----------------------------------------------------------------------===
class Instruction(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
class Instruction(User):
@property
def basic_block(self):
@ -1423,24 +1382,9 @@ class Instruction(Value):
def opcode_name(self):
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):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
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)
@ -1457,9 +1401,6 @@ class CallOrInvokeInstruction(Instruction):
class PHINode(Instruction):
def __init__(self, ptr):
Instruction.__init__(self, ptr)
@property
def incoming_count(self):
return _core.LLVMCountIncoming(self.ptr)
@ -1478,9 +1419,6 @@ class PHINode(Instruction):
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)
@ -1493,9 +1431,6 @@ class SwitchInstruction(Instruction):
class BasicBlock(Value):
def __init__(self, ptr):
Value.__init__(self, ptr)
def insert_before(self, name):
return _make_value(_core.LLVMInsertBasicBlock(self.ptr, name))
@ -1526,8 +1461,8 @@ __class_for_valueid = {
VALUE_FUNCTION : Function,
VALUE_GLOBAL_ALIAS : GlobalValue,
VALUE_GLOBAL_VARIABLE : GlobalVariable,
VALUE_UNDEF_VALUE : UndefValue,
VALUE_CONSTANT_EXPR : ConstantExpr,
VALUE_INLINE_ASM : Constant,
VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero,
VALUE_CONSTANT_INT : ConstantInt,
VALUE_CONSTANT_FP : ConstantFP,

View file

@ -237,21 +237,6 @@ unsigned LLVMInstGetOpcode(LLVMValueRef inst)
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',
* into a vector of pointers to llvm::unwrapped objects `out'. */
template <typename W, typename UW>
@ -314,6 +299,21 @@ unsigned LLVMValueGetID(LLVMValueRef value)
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,
LLVMTypeRef *types, unsigned n_types)
{

View file

@ -69,6 +69,12 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
/* Wraps llvm::Value::getValueID(). */
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(). */
LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs,
LLVMValueRef rhs);
@ -121,12 +127,6 @@ const char *LLVMInstGetOpcodeName(LLVMValueRef inst);
/* Wraps llvm::Instruction::getOpcode(). */
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
* `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */

View file

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

View file

@ -4,40 +4,69 @@
from llvm.core import *
m = None
#===----------------------------------------------------------------------===
# implement a test function
def make_function():
test_module = """
define i32 @prod(i32, i32) {
entry:
%2 = mul i32 %0, %1
ret i32 %2
}
test_module = """
define i32 @prod(i32, i32) {
entry:
%2 = mul i32 %0, %1
ret i32 %2
}
define i32 @test_func(i32, i32, i32) {
entry:
%tmp1 = call i32 @prod(i32 %0, i32 %1)
%tmp2 = add i32 %tmp1, %2
%tmp3 = add i32 %tmp2, 1
ret i32 %tmp3
}
"""
class strstream(object):
def __init__(self): pass
def read(self): return test_module
m = Module.from_assembly(strstream())
print "-"*60
print m
print "-"*60
print "Examining function `test_func':"
return m.get_function_named("test_func")
define i32 @test_func(i32, i32, i32) {
entry:
%tmp1 = call i32 @prod(i32 %0, i32 %1)
%tmp2 = add i32 %tmp1, %2
%tmp3 = add i32 %tmp2, 1
ret i32 %tmp3
}
"""
class strstream(object):
def __init__(self): pass
def read(self): return test_module
m = Module.from_assembly(strstream())
print "-"*60
print m
print "-"*60
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
for inst in func.basic_blocks[0].instructions:
for inst in test_func.basic_blocks[0].instructions:
print "Instruction #%d:" % (idx,)
print " operand_count =", inst.operand_count
print " operands:"

View file

@ -168,6 +168,21 @@ def do_value():
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():
print " Testing class Constant"
Constant.null(ti)
@ -475,6 +490,7 @@ def do_llvm_core():
do_type()
do_typehandle()
do_value()
do_user()
do_constant()
do_global_value()
do_global_variable()