Continue to implement IRBuilder

This commit is contained in:
Siu Kwan Lam 2013-01-28 17:55:52 -06:00
commit 59d0dfddc7
8 changed files with 125 additions and 19 deletions

View file

@ -52,8 +52,10 @@ def wrap(cap):
'''Wrap a PyCapsule with the corresponding Wrapper class.
If `cap` is not a PyCapsule, returns `cap`
'''
if not _capsule.check(cap): # bypass if cap is not a PyCapsule
return cap
if not _capsule.check(cap):
if isinstance(cap, list):
return map(wrap, cap)
return cap # bypass if cap is not a PyCapsule and not a list
addr = _capsule.getPointer(cap)
try:
# find cached object by pointer address
@ -77,7 +79,7 @@ def wrap(cap):
# do auto downcast
pass
else:
assert oldcls is newcls
assert oldcls is newcls, (cap, obj, oldcls, newcls)
return obj
def downcast(old, new):

View file

@ -1,6 +1,7 @@
#include <Python.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Value.h>
#include <llvm/Function.h>
#include <llvm/Support/raw_ostream.h>
@ -11,12 +12,14 @@ namespace extra{
SmallVectorImpl<char> *SV;
public:
static
raw_svector_ostream_helper* create(){
raw_svector_ostream_helper* create()
{
SmallVectorImpl<char>* sv = new SmallVector<char, 16>();
return new raw_svector_ostream_helper(sv);
}
~raw_svector_ostream_helper(){
~raw_svector_ostream_helper()
{
delete SV;
}
@ -36,7 +39,8 @@ namespace extra{
}
static
PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) {
PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args)
{
using extra::raw_svector_ostream_helper;
using llvm::raw_svector_ostream;
@ -49,7 +53,8 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) {
}
static
PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) {
PyObject* make_small_vector_from_types(PyObject* self, PyObject* args)
{
using llvm::Type;
typedef llvm::SmallVector<llvm::Type*, 8> SmallVector_Type;
@ -69,24 +74,88 @@ PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) {
return pycapsule_new(SV, "llvm::SmallVector<llvm::Type*,8>");
}
static
PyObject* make_small_vector_from_values(PyObject* self, PyObject* args)
{
using llvm::Value;
typedef llvm::SmallVector<llvm::Value*, 8> SmallVector_Value;
SmallVector_Value* SV = new SmallVector_Value;
Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject* cap = PyTuple_GetItem(args, i);
if (!cap) {
return NULL;
}
Value* value = (Value*)PyCapsule_GetPointer(cap, "llvm::Value");
if (!value) {
return NULL;
}
SV->push_back(value);
}
return pycapsule_new(SV, "llvm::SmallVector<llvm::Value*,8>");
}
static PyMethodDef extra_methodtable[] = {
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
method( make_raw_ostream_for_printing ),
method( make_small_vector_from_types ),
method( make_small_vector_from_values ),
#undef method
{ NULL }
};
////////////
PyObject* Value_use_iterator_to_list(llvm::Value* val){
typedef llvm::Value::use_iterator iterator;
template<class iterator>
PyObject* iterator_to_pylist_deref(iterator begin, iterator end,
const char *capsuleName, const char *className)
{
PyObject* list = PyList_New(0);
for (iterator it = val->use_begin(), end = val->use_end(); it != end; ++it) {
PyObject* cap = pycapsule_new(*it, "llvm::Value", "llvm::User");
for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(&*begin, capsuleName, className);
PyList_Append(list, cap);
}
return list;
}
template<class iterator>
PyObject* iterator_to_pylist(iterator begin, iterator end,
const char *capsuleName, const char *className)
{
PyObject* list = PyList_New(0);
for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(*begin, capsuleName, className);
PyList_Append(list, cap);
}
return list;
}
template<class iplist>
PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName,
const char* className){
return iterator_to_pylist_deref(IPL.begin(), IPL.end(), capsuleName,
className);
}
static
PyObject* Value_use_iterator_to_list(llvm::Value* val)
{
return iterator_to_pylist(val->use_begin(), val->use_end(),
"llvm::Value", "llvm::User");
}
static
PyObject* Function_getArgumentList(llvm::Function* fn)
{
return iplist_to_pylist(fn->getArgumentList(), "llvm::Value",
"llvm::Argument");
}
static
PyObject* Function_getBasicBlockList(llvm::Function* fn)
{
return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value",
"llvm::BasicBlock");
}

View file

@ -0,0 +1,9 @@
from binding import *
from namespace import llvm
from Value import Argument
@Argument
class Argument:
_include_ = 'llvm/Argument.h'

View file

@ -1,6 +1,6 @@
from binding import *
from namespace import llvm
from Value import GlobalValue, Constant, Function
from Value import GlobalValue, Constant, Function, Argument
from Type import Type
from DerivedTypes import FunctionType
from LLVMContext import LLVMContext
@ -17,3 +17,5 @@ class Function:
getIntrinsicID = Method(cast(Unsigned, int))
isIntrinsic = Method(cast(Bool, bool))
getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr)
getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr)

View file

@ -2,7 +2,10 @@ from binding import *
from namespace import llvm
from LLVMContext import LLVMContext
from BasicBlock import BasicBlock
from Instruction import ReturnInst
from Instruction import ReturnInst, CallInst
from SmallVector import SmallVector_Value
from StringRef import StringRef
from Value import Value
IRBuilder = llvm.Class()
@ -19,3 +22,17 @@ class IRBuilder:
isNamePreserving = Method(cast(Bool, bool))
CreateRetVoid = Method(ptr(ReturnInst))
CreateRet = Method(ptr(ReturnInst), ptr(Value))
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef))
_CreateCall |= Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value))
_CreateCall.realname = 'CreateCall'
@CustomPythonMethod
def CreateCall(self, *args):
import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return IRBuilder._CreateCall(self, *args)

View file

@ -5,3 +5,9 @@ from namespace import llvm
class SmallVector_Type:
_realname_ = 'SmallVector<llvm::Type*,8>'
delete = Destructor()
@llvm.Class()
class SmallVector_Value:
_realname_ = 'SmallVector<llvm::Value*,8>'
delete = Destructor()

View file

@ -8,6 +8,7 @@ from StringRef import StringRef
Value = llvm.Class()
# forward declarations
Argument = llvm.Class(Value)
User = llvm.Class(Value)
BasicBlock = llvm.Class(Value)
Constant = llvm.Class(User)

View file

@ -63,11 +63,11 @@ builder.SetInsertPoint(bb)
assert bb.getTerminator() is None
builder.CreateRetVoid()
arg0, arg1 = fn.getArgumentList()
print arg0, arg1
assert not bb.empty()
assert bb.getTerminator() is not None
print bb
ret = builder.CreateCall(fn, [arg0, arg1], '')
builder.CreateRet(ret)
print fn