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:]
|
argtys = self.signatures[0][1:]
|
||||||
for i, ty in enumerate(argtys):
|
for i, ty in enumerate(argtys):
|
||||||
if isinstance(ty, ownedptr):
|
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):
|
class CustomMethod(Method):
|
||||||
def __init__(self, methodname, retty, *argtys):
|
def __init__(self, methodname, retty, *argtys):
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,12 @@ _cache = defaultdict(WeakValueDictionary)
|
||||||
|
|
||||||
def release_ownership(old):
|
def release_ownership(old):
|
||||||
logger.debug('Release %s', 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):
|
def has_ownership(cap):
|
||||||
addr = Capsule.getPointer(cap)
|
addr = Capsule.getPointer(cap)
|
||||||
|
|
|
||||||
|
|
@ -340,3 +340,44 @@ PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
|
||||||
return pycapsule_new(new GenericValue(ret), GVN);
|
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
|
from StringIO import StringIO
|
||||||
api.capsule.set_debug(True)
|
api.capsule.set_debug(True)
|
||||||
|
|
||||||
|
def test_basic_jit_use():
|
||||||
api.InitializeNativeTarget()
|
api.InitializeNativeTarget()
|
||||||
context = api.getGlobalContext()
|
context = api.getGlobalContext()
|
||||||
|
|
||||||
|
|
||||||
m = api.Module.new("modname", context)
|
m = api.Module.new("modname", context)
|
||||||
print m.getModuleIdentifier()
|
print m.getModuleIdentifier()
|
||||||
m.setModuleIdentifier('modname2')
|
m.setModuleIdentifier('modname2')
|
||||||
print m.getModuleIdentifier()
|
print m.getModuleIdentifier()
|
||||||
print 'endianness', m.getEndianness()
|
print 'endianness', m.getEndianness()
|
||||||
assert m.getEndianness() == api.Module.Endianness.AnyEndianness
|
assert m.getEndianness() == api.Module.Endianness.AnyEndianness
|
||||||
print 'pointer-size', m.getPointerSize()
|
print 'pointer-size', m.getPointerSize()
|
||||||
assert m.getPointerSize() == api.Module.PointerSize.AnyPointerSize
|
assert m.getPointerSize() == api.Module.PointerSize.AnyPointerSize
|
||||||
m.dump()
|
m.dump()
|
||||||
|
|
||||||
|
|
||||||
os = extra.make_raw_ostream_for_printing()
|
os = extra.make_raw_ostream_for_printing()
|
||||||
m.print_(os, None)
|
m.print_(os, None)
|
||||||
print os.str()
|
print os.str()
|
||||||
|
|
||||||
|
|
||||||
int1ty = api.Type.getInt1Ty(context)
|
int1ty = api.Type.getInt1Ty(context)
|
||||||
int1ty.dump()
|
int1ty.dump()
|
||||||
|
|
||||||
assert int1ty.isIntegerTy(1)
|
assert int1ty.isIntegerTy(1)
|
||||||
|
|
||||||
fnty = api.FunctionType.get(int1ty, False)
|
fnty = api.FunctionType.get(int1ty, False)
|
||||||
fnty.dump()
|
fnty.dump()
|
||||||
|
|
||||||
types = [api.Type.getIntNTy(context, 8), api.Type.getIntNTy(context, 32)]
|
types = [api.Type.getIntNTy(context, 8), api.Type.getIntNTy(context, 32)]
|
||||||
fnty = api.FunctionType.get(api.Type.getIntNTy(context, 8), types, False)
|
fnty = api.FunctionType.get(api.Type.getIntNTy(context, 8), types, False)
|
||||||
|
|
||||||
print fnty
|
print fnty
|
||||||
|
|
||||||
const = m.getOrInsertFunction("foo", fnty)
|
const = m.getOrInsertFunction("foo", fnty)
|
||||||
fn = const._downcast(api.Function)
|
fn = const._downcast(api.Function)
|
||||||
print fn
|
print fn
|
||||||
assert fn.hasName()
|
assert fn.hasName()
|
||||||
assert 'foo' == fn.getName()
|
assert 'foo' == fn.getName()
|
||||||
fn.setName('bar')
|
fn.setName('bar')
|
||||||
assert 'bar' == fn.getName()
|
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.isVarArg() == False
|
||||||
assert fn.getIntrinsicID() == 0
|
assert fn.getIntrinsicID() == 0
|
||||||
assert not fn.isIntrinsic()
|
assert not fn.isIntrinsic()
|
||||||
|
|
||||||
fn_uselist = fn.list_use()
|
fn_uselist = fn.list_use()
|
||||||
assert isinstance(fn_uselist, list)
|
assert isinstance(fn_uselist, list)
|
||||||
assert len(fn_uselist) == 0
|
assert len(fn_uselist) == 0
|
||||||
|
|
||||||
builder = api.IRBuilder.new(context)
|
builder = api.IRBuilder.new(context)
|
||||||
print builder
|
print builder
|
||||||
|
|
||||||
bb = api.BasicBlock.Create(context, "entry", fn, None)
|
bb = api.BasicBlock.Create(context, "entry", fn, None)
|
||||||
assert bb.empty()
|
assert bb.empty()
|
||||||
builder.SetInsertPoint(bb)
|
builder.SetInsertPoint(bb)
|
||||||
|
|
||||||
assert bb.getTerminator() is None
|
assert bb.getTerminator() is None
|
||||||
|
|
||||||
arg0, arg1 = fn.getArgumentList()
|
arg0, arg1 = fn.getArgumentList()
|
||||||
print arg0, arg1
|
print arg0, arg1
|
||||||
|
|
||||||
extended = builder.CreateZExt(arg0, arg1.getType())
|
extended = builder.CreateZExt(arg0, arg1.getType())
|
||||||
result = builder.CreateAdd(extended, arg1)
|
result = builder.CreateAdd(extended, arg1)
|
||||||
ret = builder.CreateTrunc(result, fn.getReturnType())
|
ret = builder.CreateTrunc(result, fn.getReturnType())
|
||||||
builder.CreateRet(ret)
|
builder.CreateRet(ret)
|
||||||
|
|
||||||
print arg0.list_use()
|
print arg0.list_use()
|
||||||
|
|
||||||
print fn
|
print fn
|
||||||
|
|
||||||
errio = StringIO()
|
errio = StringIO()
|
||||||
print m
|
print m
|
||||||
|
|
||||||
ee = api.ExecutionEngine.createJIT(m, errio)
|
ee = api.ExecutionEngine.createJIT(m, errio)
|
||||||
print ee, errio.getvalue()
|
print ee, errio.getvalue()
|
||||||
print ee.getDataLayout().getStringRepresentation()
|
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(datalayout_str))
|
||||||
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))
|
||||||
|
|
||||||
fn2 = ee.FindFunctionNamed(fn.getName())
|
fn2 = ee.FindFunctionNamed(fn.getName())
|
||||||
assert fn2 is fn
|
assert fn2 is fn
|
||||||
|
|
||||||
assert ee.getPointerToFunction(fn)
|
assert ee.getPointerToFunction(fn)
|
||||||
assert ee.getPointerToNamedFunction('printf')
|
assert ee.getPointerToNamedFunction('printf')
|
||||||
|
|
||||||
gv0 = api.GenericValue.CreateInt(arg0.getType(), 12, False)
|
gv0 = api.GenericValue.CreateInt(arg0.getType(), 12, False)
|
||||||
gv1 = api.GenericValue.CreateInt(arg1.getType(), -32, True)
|
gv1 = api.GenericValue.CreateInt(arg1.getType(), -32, True)
|
||||||
|
|
||||||
assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
|
assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
|
||||||
assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()
|
assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()
|
||||||
|
|
||||||
assert gv0.toUnsignedInt() == 12
|
assert gv0.toUnsignedInt() == 12
|
||||||
assert gv1.toSignedInt() == -32
|
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