All of DataLayout, IRBuilder and started on ExecutionEngine.

This commit is contained in:
Siu Kwan Lam 2013-01-29 17:47:15 -06:00
commit 437b1e9490
20 changed files with 688 additions and 41 deletions

View file

@ -5,11 +5,15 @@ import codegen as cg
_rank = 0
namespaces = {}
RESERVED = frozenset(['None'])
class Namespace(object):
def __init__(self, name):
self.name = name
self.enums = []
self.classes = []
self.functions = []
self.includes = set()
namespaces[name] = self
def Class(self, *bases):
@ -22,6 +26,13 @@ class Namespace(object):
self.functions.append(fn)
return fn
def Enum(self, name, *value_names):
enum = Enum(*value_names)
enum.parent = self
enum.name = name
self.enums.append(enum)
return enum
@property
def fullname(self):
return self.name
@ -43,11 +54,16 @@ class BuiltinTypes(_Type):
def wrap(self, writer, var):
return var
def unwrap(self, writer, var):
return var
Void = BuiltinTypes('void')
Unsigned = BuiltinTypes('unsigned')
Uint64 = BuiltinTypes('uint64_t')
Bool = BuiltinTypes('bool')
ConstStdString = BuiltinTypes('const std::string')
PyObjectPtr = BuiltinTypes('PyObject*')
PyObjectPtr.format='O'
class Class(_Type):
format = 'O'
@ -78,6 +94,7 @@ class Class(_Type):
self.enums.append(v)
v.name = k
v.parent = self
setattr(self, k, v)
elif isinstance(v, CustomPythonMethod):
self.pymethods.append(v)
elif k == '_include_':
@ -108,7 +125,7 @@ class Class(_Type):
fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },'
for meth in self.methods:
name = meth.name
func = cg.mangle(meth.fullname)
func = meth.c_name
writer.println(fmt % locals())
writer.println('{ NULL },')
writer.println('};')
@ -161,9 +178,12 @@ class Class(_Type):
return casted
class Enum(object):
format = 'O'
def __init__(self, *value_names):
self.parent = None
self.value_names = value_names
self.includes = set()
@property
def fullname(self):
@ -191,11 +211,34 @@ class Enum(object):
writer.raises(ValueError, 'Invalid enum %s' % v)
return ret
def unwrap(self, writer, val):
tostring = 'PyString_AsString(%(val)s)' % locals()
string = writer.declare('const char*', tostring)
ret = writer.declare('%s::%s' % (self.parent, self.name))
parent = self.parent
iffmt = 'if (string_equal(%(string)s, "%(v)s"))'
for i, v in enumerate(self.value_names):
with writer.block(iffmt % locals()):
fmt = '%(ret)s = %(parent)s::%(v)s;'
writer.println(fmt % locals())
if i == 0:
iffmt = 'else ' + iffmt
with writer.block('else'):
writer.raises(ValueError, 'Invalid enum.')
return ret
def compile_cpp(self, writer):
pass
def compile_py(self, writer):
with writer.block('class %s:' % self.name):
writer.println('_llvm_type_ = "%s"' % self.fullname)
for v in self.value_names:
writer.println('%(v)s = "%(v)s"' % locals())
if v in RESERVED:
k = '%s_' % v
else:
k = v
writer.println('%(k)s = "%(v)s"' % locals())
writer.println()
class Method(object):
@ -236,11 +279,15 @@ class Method(object):
def realname(self, v):
self.__realname = v
@property
def c_name(self):
return cg.mangle("%s_%s" % (self.parent, self.name))
def __str__(self):
return self.fullname
def compile_cpp(self, writer):
with writer.py_function(self.fullname):
with writer.py_function(self.c_name):
if len(self.signatures) == 1:
sig = self.signatures[0]
retty = sig[0]
@ -270,13 +317,40 @@ class Method(object):
with decl as (this, varargs):
unwrap_this = writer.unwrap(this)
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = '.'.join([self.parent.name, self.name])
ret = writer.call('_api.%s' % func,
args=(unwrap_this,), varargs=unwrapped)
wrapped = writer.wrap(ret)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
def require_only(self, num):
'''Require only "num" of argument.
'''
assert len(self.signatures) == 1
sig = self.signatures[0]
ret = sig[0]
args = sig[1:]
arg_ct = len(args)
for i in range(num, arg_ct):
self._add_signature(ret, *args[:i])
return self
def is_return_ownedptr(self):
retty = self.signatures[0][0]
return isinstance(retty, ownedptr)
def process_ownedptr_args(self, writer, unwrapped):
argtys = self.signatures[0][1:]
for i, ty in enumerate(argtys):
if isinstance(ty, ownedptr):
writer.release_ownership('%s[%d]' % (unwrapped, i))
class CustomMethod(Method):
def __init__(self, methodname, retty, *argtys):
@ -289,7 +363,6 @@ class CustomMethod(Method):
writer.return_value(retty.wrap(writer, ret))
class StaticMethod(Method):
def compile_cpp_body(self, writer, retty, argtys):
@ -307,12 +380,24 @@ class StaticMethod(Method):
decl = writer.function(self.name, varargs='args')
with decl as varargs:
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = '.'.join([self.parent.name, self.name])
ret = writer.call('_api.%s' % func, varargs=unwrapped)
wrapped = writer.wrap(ret)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
class CustomStaticMethod(StaticMethod):
def __init__(self, methodname, retty, *argtys):
super(CustomStaticMethod, self).__init__(retty, *argtys)
self.methodname = methodname
def compile_cpp_body(self, writer, retty, argtys):
args = writer.parse_arguments('args', *argtys)
ret = writer.call(self.methodname, retty.fullname, *args)
writer.return_value(retty.wrap(writer, ret))
class Function(Method):
_kind_ = 'func'
@ -329,10 +414,11 @@ class Function(Method):
def compile_py(self, writer):
with writer.function(self.name, varargs='args') as varargs:
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = self.fullname.split('::', 1)[1].replace('::', '.')
ret = writer.call('_api.%s' % func,
varargs=unwrapped)
wrapped = writer.wrap(ret)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
@ -400,10 +486,14 @@ class ptr(_Type):
def __init__(self, element):
assert isinstance(element, Class)
self.element = element
self.const = False
@property
def fullname(self):
return '%s*' % self.element
if self.const:
return 'const %s*' % self.element
else:
return '%s*' % self.element
@property
def format(self):
@ -420,6 +510,13 @@ class ptr(_Type):
return writer.pycapsule_new(val, self.element.capsule_name,
self.element.fullname)
class ownedptr(ptr):
pass
def const(ptr):
ptr.const = True
return ptr
class cast(_Type):
format = 'O'
@ -458,7 +555,6 @@ class cast(_Type):
return ret
class CustomPythonMethod(object):
def __init__(self, fn):
src = inspect.getsource(fn)

View file

@ -23,10 +23,11 @@ class WeakRef(ref):
_pyclasses = {}
_addr2obj = WeakValueDictionary()
_owners = {}
_owners = {} # address to weak reference
def _sentry(ptr):
assert _capsule.check(ptr)
if not _capsule.check(ptr):
raise ValueError('Must provide a PyCapsule object.')
def classof(cap):
cls = _capsule.getClassName(cap)
@ -38,17 +39,16 @@ def _capsule_destructor(weak):
addr = _capsule.getPointer(cap)
cls = _capsule.getClassName(cap)
logger.debug("destroy pointer 0x%08X to %s", addr, cls)
weak.dtor(cap)
# weak.dtor(cap)
del _owners[addr]
def release_ownership(old):
addr = _capsule.getPointer(old)
if hasattr(old, '_delete_'):
oldweak = _owners[addr]
oldweak.owning = False # dis-own
del _owners[addr]
oldweak = _owners[addr]
oldweak.owning = False # dis-own
del _owners[addr]
def wrap(cap):
def wrap(cap, owned=False):
'''Wrap a PyCapsule with the corresponding Wrapper class.
If `cap` is not a PyCapsule, returns `cap`
'''
@ -66,7 +66,8 @@ def wrap(cap):
obj = cls(cap)
_addr2obj[addr] = obj # cache object by address
# set ownership if *cls* defines *_delete_*
if hasattr(cls, '_delete_'):
if not owned and hasattr(cls, '_delete_'):
assert addr not in _owners, "has existing owner"
weak = WeakRef(obj, _capsule_destructor)
_owners[addr] = weak
weak.capsule = cap
@ -84,10 +85,11 @@ def wrap(cap):
def downcast(old, new):
assert old is not new
assert _capsule.getPointer(old) not in _owners
oldcls = classof(old)
newcls = classof(new)
assert issubclass(newcls, oldcls)
release_ownership(old)
# release_ownership(old)
del _addr2obj[_capsule.getPointer(old)] # clear cache
return wrap(new)

View file

@ -104,10 +104,9 @@ class CodeWriterBase(object):
@contextlib.contextmanager
def py_function(self, name):
mangled = mangle(name)
self.println('static')
self.println('PyObject*')
with self.block('%(mangled)s(PyObject* self, PyObject* args)' % locals()):
with self.block('%(name)s(PyObject* self, PyObject* args)' % locals()):
self.used_symbols.add('self')
self.used_symbols.add('args')
yield
@ -175,7 +174,7 @@ class CppCodeWriter(CodeWriterBase):
arglist = ', '.join(args)
stmt = '%(func)s(%(arglist)s)' % locals()
if retty == 'void':
self.println(stmt)
self.println(stmt + ';')
else:
return self.declare(retty, stmt)
@ -247,6 +246,9 @@ class PyCodeWriter(CodeWriterBase):
yield
self.used_symbols = self.old
def release_ownership(self, val):
self.println('capsule.release_ownership(%(val)s)' % locals())
def unwrap_many(self, args):
unwrapped = self.new_symbol('unwrapped')
self.println('%(unwrapped)s = map(capsule.unwrap, %(args)s)' % locals())
@ -255,9 +257,9 @@ class PyCodeWriter(CodeWriterBase):
def unwrap(self, val):
return self.call('capsule.unwrap', args=(val,), ret='unwrapped')
def wrap(self, val):
def wrap(self, val, owned):
wrapped = self.new_symbol('wrapped')
self.println('%(wrapped)s = capsule.wrap(%(val)s)' % locals())
self.println('%(wrapped)s = capsule.wrap(%(val)s, %(owned)s)' % locals())
return wrapped
def call(self, func, args=(), varargs=None, ret='ret'):

View file

@ -39,6 +39,7 @@ populate_submodules(module, submodules);
def populate_headers(println):
includes = [
'cstring',
'llvm_binding/conversion.h',
'llvm_binding/binding.h',
'llvm_binding/capsule_context.h',
@ -70,6 +71,9 @@ def main():
for cls in ns.classes:
print cls
units.append(cls)
for enum in ns.enums:
print enum
units.append(enum)
# add extra stuffs
downcastlist = []
@ -84,7 +88,7 @@ def main():
units.append(fn)
# generate cpp source
# Generate C++ source
with open('%s.cpp' % outputfilename, 'w') as cppfile:
println = wrap_println_from_file(cppfile)
@ -93,6 +97,8 @@ def main():
# required headers
includes = set()
for ns in namespaces.values():
includes |= ns.includes
for u in units:
includes |= u.includes
@ -128,7 +134,7 @@ static
for u in units:
if isinstance(u, Function):
name = u.name
func = codegen.mangle(u.fullname)
func = u.c_name
writer.println(fmt % locals())
writer.println('{ NULL },')
writer.println('};')
@ -154,6 +160,7 @@ static
println(extension_entry % {'module': '_api', 'methtable': 'methtable'})
# Generate Python source
with open('%s.py' % outputfilename, 'w') as pyfile:
println = wrap_println_from_file(pyfile)
println('import _api, capsule')

View file

@ -39,6 +39,16 @@ PyObject* pycapsule_new(void* ptr,
}
static
PyObject* pycapsule_new(const void* ptr,
const char* basename,
const char* classname=NULL)
{
// Use const_cast to strip the constantness.
// Let the user take the responsibility.
return pycapsule_new(const_cast<void*>(ptr), basename, classname);
}
#endif //LLVMPY_CAPSULE_CONTEXT_H_

View file

@ -3,7 +3,7 @@
#include <llvm/Value.h>
#include <llvm/Function.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
namespace extra{
using namespace llvm;
@ -97,11 +97,34 @@ PyObject* make_small_vector_from_values(PyObject* self, PyObject* args)
}
static
PyObject* make_small_vector_from_unsigned(PyObject* self, PyObject* args)
{
using llvm::Value;
typedef llvm::SmallVector<unsigned, 8> SmallVector_Unsigned;
SmallVector_Unsigned* SV = new SmallVector_Unsigned;
Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject* item = PyTuple_GetItem(args, i);
if (!item) {
return NULL;
}
unsigned value = PyLong_AsUnsignedLong(item);
if (PyErr_Occurred()){
return NULL;
}
SV->push_back(value);
}
return pycapsule_new(SV, "llvm::SmallVector<unsigned,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 ),
method( make_small_vector_from_unsigned ),
#undef method
{ NULL }
};
@ -139,11 +162,20 @@ PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName,
className);
}
static
bool string_equal(const char *A, const char *B){
for (; *A and *B; ++A, ++B) {
if (*A != *B) return false;
}
return true;
}
////////////
static
PyObject* Value_use_iterator_to_list(llvm::Value* val)
{
return iterator_to_pylist(val->use_begin(), val->use_end(),
"llvm::Value", "llvm::User");
"llvm::Value", "llvm::User");
}
static
@ -158,4 +190,47 @@ PyObject* Function_getBasicBlockList(llvm::Function* fn)
{
return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value",
"llvm::BasicBlock");
}
}
/*
* errout --- can be any file object
*
*/
static
llvm::ExecutionEngine* ExecutionEngine_create(
llvm::Module* M,
bool ForceInterpreter = false,
PyObject* errout = 0,
llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default,
bool GVsWithCode = true)
{
using namespace llvm;
std::string ErrorStr;
ExecutionEngine *ee = ExecutionEngine::create(M, ForceInterpreter,
&ErrorStr, OptLevel,
GVsWithCode);
PyFile_WriteString(ErrorStr.c_str(), errout);
return ee;
}
/*
* errout --- can be any file object
*
*/
static
llvm::ExecutionEngine* ExecutionEngine_createJIT(
llvm::Module* M,
PyObject* errout = 0,
llvm::JITMemoryManager* JMM = 0,
llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default,
bool GCsWithCode = true,
llvm::Reloc::Model RM = llvm::Reloc::Default,
llvm::CodeModel::Model CMM = llvm::CodeModel::JITDefault)
{
using namespace llvm;
std::string ErrorStr;
ExecutionEngine *ee = ExecutionEngine::createJIT(M, &ErrorStr, JMM, OL,
GCsWithCode, RM, CMM);
PyFile_WriteString(ErrorStr.c_str(), errout);
return ee;
}

19
newbinding/src/CodeGen.py Normal file
View file

@ -0,0 +1,19 @@
from binding import *
from namespace import llvm
@llvm.Class()
class Reloc:
Model = Enum('Default', 'Static', 'PIC_', 'DynamicNoPIC')
@llvm.Class()
class CodeModel:
Model = Enum('Default', 'JITDefault', 'Small', 'Kernel', 'Medium', 'Large')
@llvm.Class()
class TLSModel:
Model = Enum('GeneralDynamic', 'LocalDynamic', 'InitialExec', 'LocalExec')
@llvm.Class()
class CodeGenOpt:
'Actually a namespace'
Level = Enum('None', 'Less', 'Default', 'Aggressive')

View file

@ -0,0 +1,97 @@
from binding import *
from namespace import llvm
from LLVMContext import LLVMContext
from StringRef import StringRef
from Module import Module
from Type import Type, IntegerType, StructType
from SmallVector import SmallVector_Value
from GlobalVariable import GlobalVariable
DataLayout = llvm.Class()
StructLayout = llvm.Class()
@DataLayout
class DataLayout:
_include_ = 'llvm/DataLayout.h'
_new_string = Constructor(cast(str, StringRef))
_new_module = Constructor(ptr(Module))
@CustomPythonStaticMethod
def new(arg):
if isinstance(arg, Module):
return DataLayout._new_module(arg)
else:
return DataLayout._new_string(arg)
delete = Destructor()
isLittleEndian = Method(cast(Bool, bool))
isBigEndian = Method(cast(Bool, bool))
getStringRepresentation = Method(cast(StringRef, str))
@CustomPythonMethod
def __str__(self):
return self.getStringRepresentation()
isLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
isIllegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
exceedsNaturalStackAlignment = Method(cast(Bool, bool), cast(int, Unsigned))
fitsInLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
getPointerABIAlignment = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerPrefAlignment = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerSize = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerSizeInBits = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getTypeSizeInBits = Method(cast(Uint64, int), ptr(Type))
getTypeStoreSize = Method(cast(Uint64, int), ptr(Type))
getTypeStoreSizeInBits = Method(cast(Uint64, int), ptr(Type))
getTypeAllocSize = Method(cast(Uint64, int), ptr(Type))
getTypeAllocSizeInBits = Method(cast(Uint64, int), ptr(Type))
getABITypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getABIIntegerTypeAlignment = Method(cast(Unsigned, int), cast(int, Unsigned))
getCallFrameTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getPrefTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getPreferredTypeAlignmentShift = Method(cast(Unsigned, int), ptr(Type))
_getIntPtrType = Method(ptr(IntegerType),
ref(LLVMContext), cast(int, Unsigned))
_getIntPtrType.require_only(1)
_getIntPtrType.realname = 'getIntPtrType'
_getIntPtrType2 = Method(ptr(Type), ptr(Type))
_getIntPtrType2.realname = 'getIntPtrType'
@CustomPythonMethod
def getIntPtrType(self, *args):
if isinstance(args[0], LLVMContext):
return self._getIntPtrType(*args)
else:
return self._getIntPtrType(*args)
_getIndexedOffset = Method(cast(Uint64, int), ptr(Type),
ref(SmallVector_Value))
_getIndexedOffset.realname = 'getIndexedOffset'
@CustomPythonMethod
def getIndexedOffset(self, *args):
import extra
args = list(args)
args[1] = extra.make_small_vector_from_values(args[1])
return self.getIndexedOffset(*args)
getStructLayout = Method(const(ptr(StructLayout)), ptr(StructType))
getPreferredAlignment = Method(cast(Unsigned, int), ptr(GlobalVariable))
getPreferredAlignmentLog = Method(cast(Unsigned, int), ptr(GlobalVariable))
@StructLayout
class StructLayout:
pass

View file

@ -0,0 +1,34 @@
from binding import *
from namespace import llvm
from Module import Module
from JITMemoryManager import JITMemoryManager
from CodeGen import CodeGenOpt, Reloc, CodeModel
from DataLayout import DataLayout
ExecutionEngine = llvm.Class()
@ExecutionEngine
class ExecutionEngine:
_include_ = ('llvm/ExecutionEngine/ExecutionEngine.h',
'llvm/ExecutionEngine/JIT.h') # force linking of jit
delete = Destructor()
create = CustomStaticMethod('ExecutionEngine_create',
ptr(ExecutionEngine),
ownedptr(Module), cast(bool, Bool),
PyObjectPtr, CodeGenOpt.Level,
cast(bool, Bool)).require_only(1)
createJIT = CustomStaticMethod('ExecutionEngine_createJIT',
ptr(ExecutionEngine),
ownedptr(Module), PyObjectPtr,
ptr(JITMemoryManager),
CodeGenOpt.Level,
cast(bool, Bool),
Reloc.Model,
CodeModel.Model).require_only(1)
addModule = Method(Void, ptr(Module))
getDataLayout = Method(const(ownedptr(DataLayout)))
removeModule = Method(cast(Bool, bool), ptr(Module))

View file

@ -0,0 +1,8 @@
from binding import *
from namespace import llvm
from GlobalValue import GlobalValue
@llvm.Class(GlobalValue)
class GlobalVariable:
pass

View file

@ -2,10 +2,16 @@ from binding import *
from namespace import llvm
from LLVMContext import LLVMContext
from BasicBlock import BasicBlock
from Instruction import ReturnInst, CallInst
from SmallVector import SmallVector_Value
from Instruction import ReturnInst, CallInst, BranchInst, SwitchInst
from Instruction import IndirectBrInst, InvokeInst, ResumeInst, PHINode
from Instruction import UnreachableInst, AllocaInst, LoadInst, StoreInst
from Instruction import FenceInst, AtomicCmpXchgInst, AtomicRMWInst, CmpInst
from Instruction import LandingPadInst, VAArgInst
from Instruction import AtomicOrdering, SynchronizationScope
from SmallVector import SmallVector_Value, SmallVector_Unsigned
from StringRef import StringRef
from Value import Value
from Value import Value, MDNode
from Type import Type, IntegerType
IRBuilder = llvm.Class()
@ -24,15 +30,238 @@ class IRBuilder:
CreateRetVoid = Method(ptr(ReturnInst))
CreateRet = Method(ptr(ReturnInst), ptr(Value))
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
CreateBr = Method(ptr(BranchInst), ptr(BasicBlock))
CreateCondBr = Method(ptr(BranchInst), ptr(Value), ptr(BasicBlock),
ptr(BasicBlock), ptr(MDNode)).require_only(3)
CreateSwitch = Method(ptr(SwitchInst), ptr(Value), ptr(BasicBlock),
cast(int, Unsigned), ptr(MDNode)).require_only(2)
CreateIndirectBr = Method(ptr(IndirectBrInst), ptr(Value),
cast(int, Unsigned)).require_only(1)
CreateInvoke = Method(ptr(InvokeInst), ptr(Value), ptr(BasicBlock),
ptr(BasicBlock), ref(SmallVector_Value),
cast(str, StringRef)).require_only(4)
CreateResume = Method(ptr(ResumeInst), ptr(Value))
CreateUnreachable = Method(ptr(UnreachableInst))
def _binop_has_nsw_nuw():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool), cast(bool, Bool)]
op = Method(*sig).require_only(2)
return op
CreateAdd = _binop_has_nsw_nuw()
CreateSub = _binop_has_nsw_nuw()
CreateMul = _binop_has_nsw_nuw()
CreateShl = _binop_has_nsw_nuw()
def _binop_is_exact():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool)]
op = Method(*sig).require_only(2)
return op
CreateUDiv = _binop_is_exact()
CreateSDiv = _binop_is_exact()
CreateLShr = _binop_is_exact()
CreateAShr = _binop_is_exact()
def _binop_basic():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef)]
op = Method(*sig).require_only(2)
return op
CreateURem = _binop_basic()
CreateSRem = _binop_basic()
CreateAnd = _binop_basic()
CreateOr = _binop_basic()
CreateXor = _binop_basic()
def _float_binop():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
ptr(MDNode)]
op = Method(*sig).require_only(2)
return op
CreateFAdd = _float_binop()
CreateFSub = _float_binop()
CreateFMul = _float_binop()
CreateFDiv = _float_binop()
CreateFRem = _float_binop()
def _unop_has_nsw_nuw():
sig = [ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool), cast(bool, Bool)]
op = Method(*sig).require_only(1)
return op
CreateNeg = _unop_has_nsw_nuw()
def _float_unop():
sig = [ptr(Value), ptr(Value), cast(str, StringRef), ptr(MDNode)]
op = Method(*sig).require_only(1)
return op
CreateFNeg = _float_unop()
CreateNot = Method(ptr(Value),
ptr(Value), cast(str, StringRef)).require_only(1)
CreateAlloca = Method(ptr(AllocaInst), ptr(Type), ptr(Value),
cast(str, StringRef)).require_only(2)
CreateLoad = Method(ptr(LoadInst),
ptr(Value), cast(str, StringRef)).require_only(1)
CreateStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
cast(bool, Bool)).require_only(2)
CreateAlignedLoad = Method(ptr(LoadInst), ptr(Value), cast(int, Unsigned),
cast(bool, Bool), cast(str, StringRef))
CreateAlignedLoad.require_only(2)
CreateAlignedStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
cast(int, Unsigned), cast(bool, Bool))
CreateAlignedStore.require_only(3)
CreateFence = Method(ptr(FenceInst),
AtomicOrdering, SynchronizationScope).require_only(1)
CreateAtomicCmpXchg = Method(ptr(AtomicCmpXchgInst), ptr(Value), ptr(Value),
ptr(Value), AtomicOrdering, SynchronizationScope)
CreateAtomicCmpXchg.require_only(4)
CreateAtomicRMW = Method(ptr(AtomicRMWInst), AtomicRMWInst.BinOp,
ptr(Value), ptr(Value), AtomicOrdering,
SynchronizationScope)
CreateAtomicRMW.require_only(4)
_CreateGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef))
_CreateGEP.require_only(2)
_CreateGEP.realname = 'CreateGEP'
@CustomPythonMethod
def CreateGEP(self, *args):
import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return self._CreateGEP(*args)
_CreateInBoundsGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef))
_CreateCall |= Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value))
_CreateInBoundsGEP.require_only(2)
_CreateInBoundsGEP.realname = 'CreateInBoundsGEP'
@CustomPythonMethod
def CreateInBoundsGEP(self, *args):
import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return self._CreateInBoundsGEP(*args)
CreateStructGEP = Method(ptr(Value), ptr(Value), cast(int, Unsigned),
cast(str, StringRef)).require_only(2)
CreateGlobalStringPtr = Method(ptr(Value), cast(str, StringRef),
cast(str, StringRef)).require_only(1)
def _value_type():
sig = [ptr(Value), ptr(Value), ptr(Type), cast(str, StringRef)]
op = Method(*sig).require_only(2)
return op
CreateTrunc = _value_type()
CreateZExt = _value_type()
CreateSExt = _value_type()
CreateZExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
cast(str, StringRef)).require_only(2)
CreateSExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
cast(str, StringRef)).require_only(2)
CreateFPToUI = _value_type()
CreateFPToSI = _value_type()
CreateUIToFP = _value_type()
CreateSIToFP = _value_type()
CreateFPTrunc = _value_type()
CreateFPExt = _value_type()
CreatePtrToInt = _value_type()
CreateIntToPtr = _value_type()
CreateBitCast = _value_type()
CreateZExtOrBitCast = _value_type()
CreateSExtOrBitCast = _value_type()
# Skip CreateCast
CreateTruncOrBitCast = _value_type()
CreateIntCast = Method(ptr(Value), ptr(Value), ptr(Type), cast(bool, Bool),
cast(str, StringRef)).require_only(3)
CreateFPCast = _value_type()
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef)).require_only(2)
_CreateCall.realname = 'CreateCall'
# Skip specialized CreateICmp* and CreateFCmp*
CreateICmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateFCmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreatePHI = Method(ptr(PHINode), ptr(Type), cast(int, Unsigned),
cast(str, StringRef)).require_only(2)
@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)
return self._CreateCall(*args)
CreateSelect = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateVAArg = Method(ptr(VAArgInst), ptr(Value), ptr(Type),
cast(str, StringRef)).require_only(2)
CreateExtractElement = _binop_basic()
CreateInsertElement = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateShuffleVector = Method(ptr(Value), ptr(Value), ptr(Value),
ptr(Value), cast(str, StringRef))
CreateShuffleVector.require_only(3)
CreateExtractValue = Method(ptr(Value), ptr(Value), ref(SmallVector_Unsigned),
cast(str, StringRef))
CreateExtractValue.require_only(2)
CreateInsertValue = Method(ptr(Value), ptr(Value), ptr(Value),
ref(SmallVector_Unsigned), cast(str, StringRef))
CreateInsertValue.require_only(3)
CreateLandingPad = Method(ptr(LandingPadInst), ptr(Type), ptr(Value),
cast(int, Unsigned), cast(str, StringRef))
CreateLandingPad.require_only(3)
CreateIsNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
CreateIsNull.require_only(1)
CreateIsNotNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
CreateIsNotNull.require_only(1)
CreatePtrDiff = _binop_basic()
# New in llvm 3.3
#CreateVectorSplat = Method(ptr(Value), cast(int, Unsigned), ptr(Value),
# cast(str, StringRef))

View file

@ -26,9 +26,9 @@ IntrinsicInst = llvm.Class(CallInst)
FCmpInst = llvm.Class(CmpInst)
ICmpInst = llvm.Class(CmpInst)
BranchInst = llvm.Class(TerminatorInst)
IndirectBrInst = llvm.Class(TerminatorInst)
InvokeInst = llvm.Class(TerminatorInst)
ResumeInst = llvm.Class(TerminatorInst)
ReturnInst = llvm.Class(TerminatorInst)
SwitchInst = llvm.Class(TerminatorInst)
@ -56,14 +56,14 @@ FPTruncInst = llvm.Class(CastInst)
class Instruction:
pass
@AtomicCmpXchgInst
class AtomicCmpXchgInst:
pass
@AtomicRMWInst
class AtomicRMWInst:
pass
BinOp = Enum('Xchg', 'Add', 'Sub', 'And', 'Nand', 'Or', 'Xor', 'Max', 'Min',
'UMax', 'UMin', 'FIRST_BINOP', 'LAST_BINOP', 'BAD_BINOP')
@BinaryOperator
class BinaryOperator:
@ -75,7 +75,17 @@ class CallInst:
@CmpInst
class CmpInst:
pass
Predicate = Enum('FCMP_FALSE', 'FCMP_OEQ', 'FCMP_OGT', 'FCMP_OGE',
'FCMP_OLT', 'FCMP_OLE', 'FCMP_ONE', 'FCMP_ORD', 'FCMP_UNO',
'FCMP_UEQ', 'FCMP_UGT', 'FCMP_UGE', 'FCMP_ULT', 'FCMP_ULE',
'FCMP_UNE', 'FCMP_TRUE', 'FIRST_FCMP_PREDICATE',
'LAST_FCMP_PREDICATE',
'BAD_FCMP_PREDICATE',
'ICMP_EQ', 'ICMP_NE', 'ICMP_UGT', 'ICMP_UGE', 'ICMP_ULT',
'ICMP_ULE', 'ICMP_SGT', 'ICMP_SGE', 'ICMP_SLT', 'ICMP_SLE',
'FIRST_ICMP_PREDICATE',
'LAST_ICMP_PREDICATE',
'BAD_ICMP_PREDICATE',)
@ExtractElementInst
class ExtractElementInst:
@ -146,11 +156,14 @@ class ICmpInst:
class BranchInst:
pass
@IndirectBrInst
class IndirectBrInst:
pass
@InvokeInst
class InvokeInst:
pass
@ResumeInst
class ResumeInst:
pass
@ -228,3 +241,12 @@ class FPToUIInst:
@FPTruncInst
class FPTruncInst:
pass
AtomicOrdering = llvm.Enum('AtomicOrdering',
'NotAtomic', 'Unordered', 'Monotonic', 'Acquire',
'Release', 'AcquireRelease',
'SequentiallyConsistent')
SynchronizationScope = llvm.Enum('SynchronizationScope',
'SingleThread', 'CrossThread')

View file

@ -0,0 +1,7 @@
from binding import *
from namespace import llvm
@llvm.Class()
class JITMemoryManager:
pass

View file

@ -0,0 +1,7 @@
from binding import *
from namespace import llvm
from Value import MDNode
@MDNode
class MDNode:
pass

View file

@ -36,7 +36,8 @@ class Module:
appendModuleInlineAsm = Method(Void, cast(str, StringRef))
# Function Accessors
getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef), ptr(FunctionType))
getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef),
ptr(FunctionType))
# Utilities
dump = Method(Void)

View file

@ -11,3 +11,7 @@ class SmallVector_Value:
_realname_ = 'SmallVector<llvm::Value*,8>'
delete = Destructor()
@llvm.Class()
class SmallVector_Unsigned:
_realname_ = 'SmallVector<unsigned,8>'
delete = Destructor()

View file

@ -0,0 +1,8 @@
from binding import *
from namespace import llvm
llvm.includes.add('llvm/Support/TargetSelect.h')
llvm.Function('InitializeNativeTarget')
#llvm.Function('InitializeAllTargets')

View file

@ -6,6 +6,7 @@ from raw_ostream import raw_ostream
Type = llvm.Class()
IntegerType = llvm.Class(Type)
CompositeType = llvm.Class(Type)
StructType = llvm.Class(CompositeType)
SequentialType = llvm.Class(CompositeType)
PointerType = llvm.Class(SequentialType)
@ -113,3 +114,6 @@ class SequentialType:
class PointerType:
pass
@StructType
class StructType:
pass

View file

@ -9,6 +9,7 @@ from StringRef import StringRef
Value = llvm.Class()
# forward declarations
Argument = llvm.Class(Value)
MDNode = llvm.Class(Value)
User = llvm.Class(Value)
BasicBlock = llvm.Class(Value)
Constant = llvm.Class(User)

View file

@ -1,7 +1,11 @@
import api
import extra
import _capsule
from StringIO import StringIO
api.capsule.set_debug(True)
api.InitializeNativeTarget()
context = api.getGlobalContext()
@ -71,3 +75,13 @@ builder.CreateRet(ret)
print fn
errio = StringIO()
ee = api.ExecutionEngine.createJIT(m)
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'
assert datalayout_str == str(api.DataLayout.new(datalayout_str))
assert datalayout_str == str(api.DataLayout.new(str(api.DataLayout.new(datalayout_str))))