Value.uses API
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@70 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
parent
8b6109d8eb
commit
d5328ef255
8 changed files with 152 additions and 17 deletions
21
llvm/_core.c
21
llvm/_core.c
|
|
@ -322,6 +322,25 @@ _wrap_objstr2none(LLVMSetValueName, LLVMValueRef)
|
|||
_wrap_obj2none(LLVMDumpValue, LLVMValueRef)
|
||||
_wrap_dumper(LLVMDumpValueToString, LLVMValueRef)
|
||||
_wrap_obj2obj(LLVMValueGetID, LLVMValueRef, int)
|
||||
_wrap_obj2obj(LLVMValueGetNumUses, LLVMValueRef, int)
|
||||
|
||||
static PyObject *
|
||||
_wLLVMValueGetUses(PyObject *self, PyObject *args)
|
||||
{
|
||||
LLVMValueRef value;
|
||||
|
||||
if (!(value = (LLVMValueRef)get_object_arg(args)))
|
||||
return NULL;
|
||||
|
||||
LLVMValueRef *uses = 0;
|
||||
unsigned n = LLVMValueGetUses(value, &uses);
|
||||
|
||||
PyObject *list = make_list_from_LLVMValueRef_array(uses, n);
|
||||
if (n > 0)
|
||||
LLVMDisposeValueRefArray(uses);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*===-- Users ------------------------------------------------------------===*/
|
||||
|
||||
|
|
@ -1117,6 +1136,8 @@ static PyMethodDef core_methods[] = {
|
|||
_method( LLVMDumpValue )
|
||||
_method( LLVMDumpValueToString )
|
||||
_method( LLVMValueGetID )
|
||||
_method( LLVMValueGetNumUses )
|
||||
_method( LLVMValueGetUses )
|
||||
|
||||
/* Users */
|
||||
|
||||
|
|
|
|||
|
|
@ -852,6 +852,14 @@ class Value(llvm.Cacheable):
|
|||
kind = _core.LLVMGetTypeKind(ptr)
|
||||
return _make_type(ptr, kind)
|
||||
|
||||
@property
|
||||
def use_count(self):
|
||||
return _core.LLVMValueGetNumUses(self.ptr)
|
||||
|
||||
@property
|
||||
def uses(self):
|
||||
return [ _make_value(v) for v in _core.LLVMValueGetUses(self.ptr) ]
|
||||
|
||||
|
||||
class User(Value):
|
||||
|
||||
|
|
|
|||
|
|
@ -299,6 +299,47 @@ unsigned LLVMValueGetID(LLVMValueRef value)
|
|||
return valuep->getValueID();
|
||||
}
|
||||
|
||||
|
||||
unsigned LLVMValueGetNumUses(LLVMValueRef value)
|
||||
{
|
||||
llvm::Value *valuep = llvm::unwrap(value);
|
||||
assert(valuep);
|
||||
|
||||
return valuep->getNumUses();
|
||||
}
|
||||
|
||||
|
||||
unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs)
|
||||
{
|
||||
llvm::Value *valuep = llvm::unwrap(value);
|
||||
assert(valuep);
|
||||
|
||||
unsigned n = valuep->getNumUses();
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
assert(refs);
|
||||
LLVMValueRef *out = (LLVMValueRef *)malloc(sizeof(LLVMValueRef) * n);
|
||||
if (!out)
|
||||
return 0;
|
||||
*refs = out;
|
||||
|
||||
memset(out, 0, sizeof(LLVMValueRef) * n);
|
||||
llvm::Value::use_iterator it = valuep->use_begin();
|
||||
while (it != valuep->use_end()) {
|
||||
*out++ = llvm::wrap(*it);
|
||||
++it;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void LLVMDisposeValueRefArray(LLVMValueRef *refs)
|
||||
{
|
||||
assert(refs);
|
||||
free(refs);
|
||||
}
|
||||
|
||||
unsigned LLVMUserGetNumOperands(LLVMValueRef user)
|
||||
{
|
||||
llvm::User *userp = llvm::unwrap<llvm::User>(user);
|
||||
|
|
|
|||
12
llvm/extra.h
12
llvm/extra.h
|
|
@ -69,6 +69,18 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
|
|||
/* Wraps llvm::Value::getValueID(). */
|
||||
unsigned LLVMValueGetID(LLVMValueRef value);
|
||||
|
||||
/* Wraps llvm::Value::getNumUses(). */
|
||||
unsigned LLVMValueGetNumUses(LLVMValueRef value);
|
||||
|
||||
/* Wraps llvm::Value::use_{begin,end}. Allocates LLVMValueRef's as
|
||||
* required. Number of objects are returned as return value. If that is
|
||||
* greater than zero, the pointer given out must be freed by a
|
||||
* subsequent call to LLVMDisposeValueRefArray(). */
|
||||
unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs);
|
||||
|
||||
/* See above. */
|
||||
void LLVMDisposeValueRefArray(LLVMValueRef *refs);
|
||||
|
||||
/* Wraps llvm:User::getNumOperands(). */
|
||||
unsigned LLVMUserGetNumOperands(LLVMValueRef user);
|
||||
|
||||
|
|
|
|||
31
llvm/wrap.c
31
llvm/wrap.c
|
|
@ -98,19 +98,22 @@ void **make_array_from_list(PyObject *list, int n)
|
|||
return arr;
|
||||
}
|
||||
|
||||
PyObject *make_list_from_LLVMTypeRef_array(LLVMTypeRef *p, unsigned n)
|
||||
{
|
||||
size_t i;
|
||||
PyObject *list = PyList_New(n);
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
PyObject *elem = ctor_LLVMTypeRef(p[i]);
|
||||
PyList_SetItem(list, i, elem);
|
||||
}
|
||||
|
||||
return list;
|
||||
#define LIST_FROM_ARRAY_IMPL(TYPE) \
|
||||
PyObject *make_list_from_ ## TYPE ## _array( TYPE *p, unsigned n) \
|
||||
{ \
|
||||
size_t i; \
|
||||
PyObject *list = PyList_New(n); \
|
||||
\
|
||||
if (!list) \
|
||||
return NULL; \
|
||||
\
|
||||
for (i=0; i<n; i++) { \
|
||||
PyObject *elem = ctor_ ## TYPE (p[i]); \
|
||||
PyList_SetItem(list, i, elem); \
|
||||
} \
|
||||
\
|
||||
return list; \
|
||||
}
|
||||
|
||||
LIST_FROM_ARRAY_IMPL(LLVMTypeRef)
|
||||
LIST_FROM_ARRAY_IMPL(LLVMValueRef)
|
||||
|
|
|
|||
|
|
@ -98,12 +98,15 @@ void *get_object_arg(PyObject *args);
|
|||
void **make_array_from_list(PyObject *list, int n);
|
||||
|
||||
/**
|
||||
* Given an array of LLVMTypeRef's, create a PyList object. Note that
|
||||
* currently such an action is required only for LLVMTypeRef's, when
|
||||
* it is required another type, this method has to be generalized.
|
||||
* Given an array of LLVMTypeRef's, create a PyList object.
|
||||
*/
|
||||
PyObject *make_list_from_LLVMTypeRef_array(LLVMTypeRef *p, unsigned n);
|
||||
|
||||
/**
|
||||
* Given an array of LLVMValueRef's, create a PyList object.
|
||||
*/
|
||||
PyObject *make_list_from_LLVMValueRef_array(LLVMValueRef *p, unsigned n);
|
||||
|
||||
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
/* Wrapper macros */
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ def do_value():
|
|||
s = str(k)
|
||||
s = k == Constant.int(ti, 43)
|
||||
i = k.value_id
|
||||
i = k.use_count
|
||||
i = k.uses
|
||||
|
||||
|
||||
def do_user():
|
||||
|
|
|
|||
45
test/uses.py
Executable file
45
test/uses.py
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from llvm.core import *
|
||||
|
||||
m = Module.new('a')
|
||||
t = Type.int()
|
||||
ft = Type.function(t, [t, t, t])
|
||||
f = m.add_function(ft, "func")
|
||||
b = f.append_basic_block('entry')
|
||||
bld = Builder.new(b)
|
||||
tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1")
|
||||
tmp2 = bld.add(tmp1, f.args[1], "tmp2")
|
||||
tmp3 = bld.add(tmp1, f.args[2], "tmp3")
|
||||
bld.ret(tmp3)
|
||||
|
||||
print "-"*60
|
||||
print m
|
||||
print "-"*60
|
||||
|
||||
print "Testing use count ..",
|
||||
c1 = f.args[0].use_count == 1
|
||||
c2 = f.args[1].use_count == 1
|
||||
c3 = f.args[2].use_count == 1
|
||||
c4 = tmp1.use_count == 2
|
||||
c5 = tmp2.use_count == 0
|
||||
c6 = tmp3.use_count == 1
|
||||
if c1 and c2 and c3 and c4 and c5 and c6:
|
||||
print "OK"
|
||||
else:
|
||||
print "FAIL"
|
||||
|
||||
print "Testing uses ..",
|
||||
c1 = f.args[0].uses[0] is tmp1
|
||||
c2 = len(f.args[0].uses) == 1
|
||||
c3 = f.args[1].uses[0] is tmp2
|
||||
c4 = len(f.args[1].uses) == 1
|
||||
c5 = f.args[2].uses[0] is tmp3
|
||||
c6 = len(f.args[2].uses) == 1
|
||||
c7 = len(tmp1.uses) == 2
|
||||
c8 = len(tmp2.uses) == 0
|
||||
c9 = len(tmp3.uses) == 1
|
||||
if c1 and c2 and c3 and c4 and c5 and c6 and c7 and c8 and c9:
|
||||
print "OK"
|
||||
else:
|
||||
print "FAIL"
|
||||
Loading…
Add table
Add a link
Reference in a new issue