Continue to implement IRBuilder
This commit is contained in:
parent
895d114730
commit
59d0dfddc7
8 changed files with 125 additions and 19 deletions
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
9
newbinding/src/Argument.py
Normal file
9
newbinding/src/Argument.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from binding import *
|
||||
from namespace import llvm
|
||||
from Value import Argument
|
||||
|
||||
@Argument
|
||||
class Argument:
|
||||
_include_ = 'llvm/Argument.h'
|
||||
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue