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

View file

@ -1,6 +1,7 @@
#include <Python.h> #include <Python.h>
#include <llvm/ADT/SmallVector.h> #include <llvm/ADT/SmallVector.h>
#include <llvm/Value.h> #include <llvm/Value.h>
#include <llvm/Function.h>
#include <llvm/Support/raw_ostream.h> #include <llvm/Support/raw_ostream.h>
@ -11,12 +12,14 @@ namespace extra{
SmallVectorImpl<char> *SV; SmallVectorImpl<char> *SV;
public: public:
static static
raw_svector_ostream_helper* create(){ raw_svector_ostream_helper* create()
{
SmallVectorImpl<char>* sv = new SmallVector<char, 16>(); SmallVectorImpl<char>* sv = new SmallVector<char, 16>();
return new raw_svector_ostream_helper(sv); return new raw_svector_ostream_helper(sv);
} }
~raw_svector_ostream_helper(){ ~raw_svector_ostream_helper()
{
delete SV; delete SV;
} }
@ -36,7 +39,8 @@ namespace extra{
} }
static 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 extra::raw_svector_ostream_helper;
using llvm::raw_svector_ostream; using llvm::raw_svector_ostream;
@ -49,7 +53,8 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) {
} }
static static
PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) { PyObject* make_small_vector_from_types(PyObject* self, PyObject* args)
{
using llvm::Type; using llvm::Type;
typedef llvm::SmallVector<llvm::Type*, 8> SmallVector_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>"); 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[] = { static PyMethodDef extra_methodtable[] = {
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL } #define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
method( make_raw_ostream_for_printing ), method( make_raw_ostream_for_printing ),
method( make_small_vector_from_types ), method( make_small_vector_from_types ),
method( make_small_vector_from_values ),
#undef method #undef method
{ NULL } { NULL }
}; };
//////////// ////////////
template<class iterator>
PyObject* Value_use_iterator_to_list(llvm::Value* val){ PyObject* iterator_to_pylist_deref(iterator begin, iterator end,
typedef llvm::Value::use_iterator iterator; const char *capsuleName, const char *className)
{
PyObject* list = PyList_New(0); PyObject* list = PyList_New(0);
for (iterator it = val->use_begin(), end = val->use_end(); it != end; ++it) { for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(*it, "llvm::Value", "llvm::User"); PyObject* cap = pycapsule_new(&*begin, capsuleName, className);
PyList_Append(list, cap); PyList_Append(list, cap);
} }
return list; 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 binding import *
from namespace import llvm from namespace import llvm
from Value import GlobalValue, Constant, Function from Value import GlobalValue, Constant, Function, Argument
from Type import Type from Type import Type
from DerivedTypes import FunctionType from DerivedTypes import FunctionType
from LLVMContext import LLVMContext from LLVMContext import LLVMContext
@ -17,3 +17,5 @@ class Function:
getIntrinsicID = Method(cast(Unsigned, int)) getIntrinsicID = Method(cast(Unsigned, int))
isIntrinsic = Method(cast(Bool, bool)) 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 namespace import llvm
from LLVMContext import LLVMContext from LLVMContext import LLVMContext
from BasicBlock import BasicBlock 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() IRBuilder = llvm.Class()
@ -19,3 +22,17 @@ class IRBuilder:
isNamePreserving = Method(cast(Bool, bool)) isNamePreserving = Method(cast(Bool, bool))
CreateRetVoid = Method(ptr(ReturnInst)) 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: class SmallVector_Type:
_realname_ = 'SmallVector<llvm::Type*,8>' _realname_ = 'SmallVector<llvm::Type*,8>'
delete = Destructor() 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() Value = llvm.Class()
# forward declarations # forward declarations
Argument = llvm.Class(Value)
User = llvm.Class(Value) User = llvm.Class(Value)
BasicBlock = llvm.Class(Value) BasicBlock = llvm.Class(Value)
Constant = llvm.Class(User) Constant = llvm.Class(User)

View file

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