binding for EngineBuilder
This commit is contained in:
parent
78f9c9a610
commit
ca0a2b9fdd
6 changed files with 206 additions and 75 deletions
|
|
@ -358,7 +358,8 @@ class Method(object):
|
|||
argtys = self.signatures[0][1:]
|
||||
for i, ty in enumerate(argtys):
|
||||
if isinstance(ty, ownedptr):
|
||||
writer.release_ownership('%s[%d]' % (unwrapped, i))
|
||||
with writer.block('if len(%s) > %d:' % (unwrapped, i)):
|
||||
writer.release_ownership('%s[%d]' % (unwrapped, i))
|
||||
|
||||
class CustomMethod(Method):
|
||||
def __init__(self, methodname, retty, *argtys):
|
||||
|
|
|
|||
|
|
@ -91,7 +91,12 @@ _cache = defaultdict(WeakValueDictionary)
|
|||
|
||||
def release_ownership(old):
|
||||
logger.debug('Release %s', old)
|
||||
_addr2dtor[Capsule.getPointer(old)] = None
|
||||
addr = Capsule.getPointer(old)
|
||||
if _addr2dtor[addr] is None:
|
||||
# Guard deduplicated release
|
||||
raise Exception("Already released")
|
||||
_addr2dtor[addr] = None
|
||||
|
||||
|
||||
def has_ownership(cap):
|
||||
addr = Capsule.getPointer(cap)
|
||||
|
|
|
|||
|
|
@ -340,3 +340,44 @@ PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
|
|||
return pycapsule_new(new GenericValue(ret), GVN);
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* EngineBuilder_setErrorStr(llvm::EngineBuilder* eb, PyObject* fileobj)
|
||||
{
|
||||
|
||||
if (!PyFile_Check(fileobj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a file object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
eb->setErrorStr(&buffer);
|
||||
|
||||
if (-1 == PyFile_WriteString(buffer.c_str(), fileobj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pycapsule_new(eb, "llvm::EngineBuilder");
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* EngineBuilder_setMAttrs(llvm::EngineBuilder* eb,
|
||||
PyObject* strlist)
|
||||
{
|
||||
if (!PyList_Check(strlist)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a list of string.");
|
||||
return NULL;
|
||||
}
|
||||
std::vector<const char*> tmp;
|
||||
const int N = PyList_Size(strlist);
|
||||
tmp.reserve(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
const char * elem = PyString_AsString(PyList_GetItem(strlist, i));
|
||||
if (!elem) {
|
||||
return NULL;
|
||||
}
|
||||
tmp.push_back(elem);
|
||||
}
|
||||
eb->setMAttrs(tmp);
|
||||
return pycapsule_new(eb, "llvm::EngineBuilder");
|
||||
}
|
||||
|
||||
|
|
|
|||
49
newbinding/src/EngineBuilder.py
Normal file
49
newbinding/src/EngineBuilder.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
from binding import *
|
||||
from namespace import llvm
|
||||
from Module import Module
|
||||
from JITMemoryManager import JITMemoryManager
|
||||
from CodeGen import CodeGenOpt, Reloc, CodeModel
|
||||
from StringRef import StringRef
|
||||
from ExecutionEngine import ExecutionEngine
|
||||
from TargetMachine import TargetMachine
|
||||
|
||||
EngineBuilder = llvm.Class()
|
||||
|
||||
@llvm.Class() # a fake class (actually a namespace)
|
||||
class EngineKind:
|
||||
Kind = Enum('JIT', 'Interpreter')
|
||||
|
||||
@EngineBuilder
|
||||
class EngineBuilder:
|
||||
new = Constructor(ownedptr(Module))
|
||||
delete = Destructor()
|
||||
|
||||
def _setter(*args):
|
||||
return Method(ref(EngineBuilder), *args)
|
||||
|
||||
setEngineKind = _setter(EngineKind.Kind)
|
||||
setJITMemoryManager = _setter(ptr(JITMemoryManager))
|
||||
|
||||
setErrorStr = CustomMethod('EngineBuilder_setErrorStr',
|
||||
PyObjectPtr, PyObjectPtr)
|
||||
|
||||
setOptLevel = _setter(CodeGenOpt.Level)
|
||||
#setTargetOptions =
|
||||
setRelocationModel = _setter(Reloc.Model)
|
||||
setCodeModel = _setter(CodeModel.Model)
|
||||
setAllocateGVsWithCode = _setter(cast(bool, Bool))
|
||||
setMArch = _setter(cast(str, StringRef))
|
||||
setMCPU = _setter(cast(str, StringRef))
|
||||
setUseMCJIT = _setter(cast(bool, Bool))
|
||||
_setMAttrs = CustomMethod('EngineBuilder_setMAttrs',
|
||||
PyObjectPtr, PyObjectPtr)
|
||||
@CustomPythonMethod
|
||||
def setMAttrs(self, attrs):
|
||||
attrlist = list(str(a) for a in attrs)
|
||||
return self._setMAttrs(attrlist)
|
||||
|
||||
create = Method(ptr(ExecutionEngine),
|
||||
ownedptr(TargetMachine)).require_only(0)
|
||||
|
||||
selectTarget = Method(ptr(TargetMachine))
|
||||
|
||||
11
newbinding/src/TargetMachine.py
Normal file
11
newbinding/src/TargetMachine.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from binding import *
|
||||
from namespace import llvm
|
||||
|
||||
TargetMachine = llvm.Class()
|
||||
|
||||
@TargetMachine
|
||||
class TargetMachine:
|
||||
_include_ = 'llvm/Target/TargetMachine.h'
|
||||
delete = Destructor()
|
||||
|
||||
|
||||
|
|
@ -4,111 +4,135 @@ import _capsule
|
|||
from StringIO import StringIO
|
||||
api.capsule.set_debug(True)
|
||||
|
||||
|
||||
api.InitializeNativeTarget()
|
||||
context = api.getGlobalContext()
|
||||
def test_basic_jit_use():
|
||||
api.InitializeNativeTarget()
|
||||
context = api.getGlobalContext()
|
||||
|
||||
|
||||
m = api.Module.new("modname", context)
|
||||
print m.getModuleIdentifier()
|
||||
m.setModuleIdentifier('modname2')
|
||||
print m.getModuleIdentifier()
|
||||
print 'endianness', m.getEndianness()
|
||||
assert m.getEndianness() == api.Module.Endianness.AnyEndianness
|
||||
print 'pointer-size', m.getPointerSize()
|
||||
assert m.getPointerSize() == api.Module.PointerSize.AnyPointerSize
|
||||
m.dump()
|
||||
m = api.Module.new("modname", context)
|
||||
print m.getModuleIdentifier()
|
||||
m.setModuleIdentifier('modname2')
|
||||
print m.getModuleIdentifier()
|
||||
print 'endianness', m.getEndianness()
|
||||
assert m.getEndianness() == api.Module.Endianness.AnyEndianness
|
||||
print 'pointer-size', m.getPointerSize()
|
||||
assert m.getPointerSize() == api.Module.PointerSize.AnyPointerSize
|
||||
m.dump()
|
||||
|
||||
|
||||
os = extra.make_raw_ostream_for_printing()
|
||||
m.print_(os, None)
|
||||
print os.str()
|
||||
os = extra.make_raw_ostream_for_printing()
|
||||
m.print_(os, None)
|
||||
print os.str()
|
||||
|
||||
|
||||
int1ty = api.Type.getInt1Ty(context)
|
||||
int1ty.dump()
|
||||
int1ty = api.Type.getInt1Ty(context)
|
||||
int1ty.dump()
|
||||
|
||||
assert int1ty.isIntegerTy(1)
|
||||
assert int1ty.isIntegerTy(1)
|
||||
|
||||
fnty = api.FunctionType.get(int1ty, False)
|
||||
fnty.dump()
|
||||
fnty = api.FunctionType.get(int1ty, False)
|
||||
fnty.dump()
|
||||
|
||||
types = [api.Type.getIntNTy(context, 8), api.Type.getIntNTy(context, 32)]
|
||||
fnty = api.FunctionType.get(api.Type.getIntNTy(context, 8), types, False)
|
||||
types = [api.Type.getIntNTy(context, 8), api.Type.getIntNTy(context, 32)]
|
||||
fnty = api.FunctionType.get(api.Type.getIntNTy(context, 8), types, False)
|
||||
|
||||
print fnty
|
||||
print fnty
|
||||
|
||||
const = m.getOrInsertFunction("foo", fnty)
|
||||
fn = const._downcast(api.Function)
|
||||
print fn
|
||||
assert fn.hasName()
|
||||
assert 'foo' == fn.getName()
|
||||
fn.setName('bar')
|
||||
assert 'bar' == fn.getName()
|
||||
const = m.getOrInsertFunction("foo", fnty)
|
||||
fn = const._downcast(api.Function)
|
||||
print fn
|
||||
assert fn.hasName()
|
||||
assert 'foo' == fn.getName()
|
||||
fn.setName('bar')
|
||||
assert 'bar' == fn.getName()
|
||||
|
||||
assert fn.getReturnType().isIntegerTy(8)
|
||||
assert fn.getReturnType().isIntegerTy(8)
|
||||
|
||||
assert fnty is fn.getFunctionType()
|
||||
assert fnty is fn.getFunctionType()
|
||||
|
||||
assert fn.isVarArg() == False
|
||||
assert fn.getIntrinsicID() == 0
|
||||
assert not fn.isIntrinsic()
|
||||
assert fn.isVarArg() == False
|
||||
assert fn.getIntrinsicID() == 0
|
||||
assert not fn.isIntrinsic()
|
||||
|
||||
fn_uselist = fn.list_use()
|
||||
assert isinstance(fn_uselist, list)
|
||||
assert len(fn_uselist) == 0
|
||||
fn_uselist = fn.list_use()
|
||||
assert isinstance(fn_uselist, list)
|
||||
assert len(fn_uselist) == 0
|
||||
|
||||
builder = api.IRBuilder.new(context)
|
||||
print builder
|
||||
builder = api.IRBuilder.new(context)
|
||||
print builder
|
||||
|
||||
bb = api.BasicBlock.Create(context, "entry", fn, None)
|
||||
assert bb.empty()
|
||||
builder.SetInsertPoint(bb)
|
||||
bb = api.BasicBlock.Create(context, "entry", fn, None)
|
||||
assert bb.empty()
|
||||
builder.SetInsertPoint(bb)
|
||||
|
||||
assert bb.getTerminator() is None
|
||||
assert bb.getTerminator() is None
|
||||
|
||||
arg0, arg1 = fn.getArgumentList()
|
||||
print arg0, arg1
|
||||
arg0, arg1 = fn.getArgumentList()
|
||||
print arg0, arg1
|
||||
|
||||
extended = builder.CreateZExt(arg0, arg1.getType())
|
||||
result = builder.CreateAdd(extended, arg1)
|
||||
ret = builder.CreateTrunc(result, fn.getReturnType())
|
||||
builder.CreateRet(ret)
|
||||
extended = builder.CreateZExt(arg0, arg1.getType())
|
||||
result = builder.CreateAdd(extended, arg1)
|
||||
ret = builder.CreateTrunc(result, fn.getReturnType())
|
||||
builder.CreateRet(ret)
|
||||
|
||||
print arg0.list_use()
|
||||
print arg0.list_use()
|
||||
|
||||
print fn
|
||||
print fn
|
||||
|
||||
errio = StringIO()
|
||||
print m
|
||||
errio = StringIO()
|
||||
print m
|
||||
|
||||
ee = api.ExecutionEngine.createJIT(m, errio)
|
||||
print ee, errio.getvalue()
|
||||
print ee.getDataLayout().getStringRepresentation()
|
||||
ee = api.ExecutionEngine.createJIT(m, errio)
|
||||
print ee, errio.getvalue()
|
||||
print ee.getDataLayout().getStringRepresentation()
|
||||
|
||||
datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64'
|
||||
datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64'
|
||||
|
||||
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
|
||||
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
||||
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
|
||||
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
||||
|
||||
fn2 = ee.FindFunctionNamed(fn.getName())
|
||||
assert fn2 is fn
|
||||
fn2 = ee.FindFunctionNamed(fn.getName())
|
||||
assert fn2 is fn
|
||||
|
||||
assert ee.getPointerToFunction(fn)
|
||||
assert ee.getPointerToNamedFunction('printf')
|
||||
assert ee.getPointerToFunction(fn)
|
||||
assert ee.getPointerToNamedFunction('printf')
|
||||
|
||||
gv0 = api.GenericValue.CreateInt(arg0.getType(), 12, False)
|
||||
gv1 = api.GenericValue.CreateInt(arg1.getType(), -32, True)
|
||||
gv0 = api.GenericValue.CreateInt(arg0.getType(), 12, False)
|
||||
gv1 = api.GenericValue.CreateInt(arg1.getType(), -32, True)
|
||||
|
||||
assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
|
||||
assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()
|
||||
assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
|
||||
assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()
|
||||
|
||||
assert gv0.toUnsignedInt() == 12
|
||||
assert gv1.toSignedInt() == -32
|
||||
assert gv0.toUnsignedInt() == 12
|
||||
assert gv1.toSignedInt() == -32
|
||||
|
||||
gv1 = api.GenericValue.CreateInt(arg1.getType(), 32, False)
|
||||
gv1 = api.GenericValue.CreateInt(arg1.getType(), 32, False)
|
||||
|
||||
gvR = ee.runFunction(fn, (gv0, gv1))
|
||||
gvR = ee.runFunction(fn, (gv0, gv1))
|
||||
|
||||
assert 44 == gvR.toUnsignedInt()
|
||||
assert 44 == gvR.toUnsignedInt()
|
||||
|
||||
def test_engine_builder():
|
||||
api.InitializeNativeTarget()
|
||||
context = api.getGlobalContext()
|
||||
|
||||
m = api.Module.new("modname", context)
|
||||
|
||||
eb = api.EngineBuilder.new(m)
|
||||
eb2 = eb.setEngineKind(api.EngineKind.Kind.JIT)
|
||||
assert eb is eb2
|
||||
eb.setOptLevel(api.CodeGenOpt.Level.Aggressive).setUseMCJIT(False)
|
||||
|
||||
tm = eb.selectTarget()
|
||||
ee = eb.create(tm)
|
||||
|
||||
|
||||
def main():
|
||||
for name, value in globals().items():
|
||||
if name.startswith('test_') and callable(value):
|
||||
print name.center(80, '-')
|
||||
value()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue