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,6 +358,7 @@ 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):
with writer.block('if len(%s) > %d:' % (unwrapped, i)):
writer.release_ownership('%s[%d]' % (unwrapped, i)) writer.release_ownership('%s[%d]' % (unwrapped, i))
class CustomMethod(Method): class CustomMethod(Method):

View file

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

View file

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

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,7 +4,7 @@ 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()
@ -112,3 +112,27 @@ 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()