diff --git a/llvm/_core.c b/llvm/_core.c index 506480d..80466b3 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -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 ) diff --git a/llvm/core.py b/llvm/core.py index 0d252b5..aa75a21 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -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, diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 3fac3af..0c8af47 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -237,21 +237,6 @@ unsigned LLVMInstGetOpcode(LLVMValueRef inst) return instp->getOpcode(); } -unsigned LLVMInstGetNumOperands(LLVMValueRef inst) -{ - llvm::Instruction *instp = llvm::unwrap(inst); - assert(instp); - return instp->getNumOperands(); -} - -LLVMValueRef LLVMInstGetOperand(LLVMValueRef inst, unsigned idx) -{ - llvm::Instruction *instp = llvm::unwrap(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 @@ -314,6 +299,21 @@ unsigned LLVMValueGetID(LLVMValueRef value) return valuep->getValueID(); } +unsigned LLVMUserGetNumOperands(LLVMValueRef user) +{ + llvm::User *userp = llvm::unwrap(user); + assert(userp); + return userp->getNumOperands(); +} + +LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx) +{ + llvm::User *userp = llvm::unwrap(user); + assert(userp); + llvm::Value *operand = userp->getOperand(idx); + return llvm::wrap(operand); +} + LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id, LLVMTypeRef *types, unsigned n_types) { diff --git a/llvm/extra.h b/llvm/extra.h index 8e89391..d09e586 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -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(). */ diff --git a/test/objcache.py b/test/objcache.py index 345f873..8cca99c 100644 --- a/test/objcache.py +++ b/test/objcache.py @@ -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) diff --git a/test/operands.py b/test/operands.py index d348ecf..26d63e5 100755 --- a/test/operands.py +++ b/test/operands.py @@ -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:" diff --git a/test/testall.py b/test/testall.py index b7d5dbc..cb571fd 100644 --- a/test/testall.py +++ b/test/testall.py @@ -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()