binding for EngineBuilder

This commit is contained in:
Siu Kwan Lam 2013-02-01 11:45:19 -06:00
commit ca0a2b9fdd
6 changed files with 206 additions and 75 deletions

View file

@ -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):

View file

@ -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)

View file

@ -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");
}

View 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))

View 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()

View file

@ -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()