[pypy-svn] r65643 - in pypy/branch/pyjitpl5-experiments/pypy/jit/backend: llvm test
arigo at codespeak.net
arigo at codespeak.net
Sun Jun 7 17:19:36 CEST 2009
Author: arigo
Date: Sun Jun 7 17:19:35 2009
New Revision: 65643
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py
Log:
generate_CALL.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py Sun Jun 7 17:19:35 2009
@@ -126,6 +126,7 @@
LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type
rffi.UINT], # address space
LLVMTypeRef)
+LLVMVoidType = llexternal('LLVMVoidType', [], LLVMTypeRef)
LLVMTypeOf = llexternal('LLVMTypeOf', [LLVMValueRef], LLVMTypeRef)
LLVMConstNull = llexternal('LLVMConstNull', [LLVMTypeRef], LLVMValueRef)
@@ -239,6 +240,12 @@
LLVMTypeRef, # destination type
rffi.CCHARP], # name of result
LLVMValueRef)
+LLVMBuildIntToPtr = llexternal('LLVMBuildIntToPtr',
+ [LLVMBuilderRef, # builder
+ LLVMValueRef, # value
+ LLVMTypeRef, # destination type
+ rffi.CCHARP], # name of result
+ LLVMValueRef)
LLVMBuildBitCast = llexternal('LLVMBuildBitCast',
[LLVMBuilderRef, # builder
LLVMValueRef, # value
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py Sun Jun 7 17:19:35 2009
@@ -28,16 +28,21 @@
self.in_out_args = []
self._descr_caches = {}
self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
+ if sys.maxint == 2147483647:
+ self.size_of_int = 4
+ else:
+ self.size_of_int = 8
def setup_once(self):
if not we_are_translated():
llvm_rffi.teardown_now()
llvm_rffi.LLVM_SetFlags()
self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit")
- if sys.maxint == 2147483647:
+ if self.size_of_int == 4:
self.ty_int = llvm_rffi.LLVMInt32Type()
else:
self.ty_int = llvm_rffi.LLVMInt64Type()
+ self.ty_void = llvm_rffi.LLVMVoidType()
self.ty_bit = llvm_rffi.LLVMInt1Type()
self.ty_char = llvm_rffi.LLVMInt8Type()
self.ty_char_ptr = llvm_rffi.LLVMPointerType(self.ty_char, 0)
@@ -143,6 +148,14 @@
return llvmconstptr
_make_const._annspecialcase_ = 'specialize:argtype(1)'
+ def _lltype2llvmtype(self, TYPE):
+ if TYPE is lltype.Void:
+ return self.ty_void
+ elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
+ return self.ty_char_ptr
+ else:
+ return self.ty_int
+
def _get_var_type(self, v):
if v.type == INT:
return self.ty_int
@@ -231,12 +244,46 @@
self._descr_caches['field', S, fieldname] = descr
return descr
+ def calldescrof(self, FUNC, ARGS, RESULT):
+ try:
+ return self._descr_caches['call', ARGS, RESULT]
+ except KeyError:
+ pass
+ #
+ param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef),
+ len(ARGS), flavor='raw')
+ for i in range(len(ARGS)):
+ param_types[i] = self._lltype2llvmtype(ARGS[i])
+ ty_func = llvm_rffi.LLVMFunctionType(self._lltype2llvmtype(RESULT),
+ param_types, len(ARGS), 0)
+ lltype.free(param_types, flavor='raw')
+ ty_funcptr = llvm_rffi.LLVMPointerType(ty_func, 0)
+ #
+ result_mask = -1
+ if RESULT is lltype.Void:
+ pass
+ elif isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc':
+ pass
+ else:
+ result_size = symbolic.get_size(RESULT,
+ self.translate_support_code)
+ if result_size < self.size_of_int:
+ result_mask = (1 << (result_size*8)) - 1
+ descr = CallDescr(ty_funcptr, result_mask)
+ self._descr_caches['call', ARGS, RESULT] = descr
+ return descr
+
class FieldDescr(AbstractDescr):
def __init__(self, offset, size):
self.offset = offset
self.size = size # set to -1 to mark a pointer field
+class CallDescr(AbstractDescr):
+ def __init__(self, ty_function_ptr, result_mask=-1):
+ self.ty_function_ptr = ty_function_ptr
+ self.result_mask = result_mask
+
# ____________________________________________________________
class LLVMJITCompiler(object):
@@ -643,6 +690,37 @@
# XXX mask for char fields
llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
+ def generate_CALL(self, op):
+ calldescr = op.descr
+ assert isinstance(calldescr, CallDescr)
+ v = op.args[0]
+ if isinstance(v, ConstInt):
+ func = self.cpu._make_const(v.value, calldescr.ty_function_ptr)
+ else:
+ func = self.getintarg(v)
+ func = llvm_rffi.LLVMBuildIntToPtr(self.builder,
+ func,
+ calldescr.ty_function_ptr, "")
+ nb_args = len(op.args) - 1
+ arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), nb_args,
+ flavor='raw')
+ for i in range(nb_args):
+ v = op.args[1 + i]
+ if v.type == INT:
+ value_ref = self.getintarg(v)
+ else:
+ value_ref = self.getptrarg(v)
+ arglist[i] = value_ref
+ res = llvm_rffi.LLVMBuildCall(self.builder,
+ func, arglist, nb_args, "")
+ lltype.free(arglist, flavor='raw')
+ if op.result is not None:
+ if calldescr.result_mask != -1:
+ mask = self.cpu._make_const_int(calldescr.result_mask)
+ res = llvm_rffi.LLVMBuildAnd(self.builder,
+ res, mask, "")
+ self.vars[op.result] = res
+
# ____________________________________________________________
class MissingOperation(Exception):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py Sun Jun 7 17:19:35 2009
@@ -84,6 +84,21 @@
calldescr)
assert x.value == ord('B')
+ def test_call(self):
+ from pypy.rpython.annlowlevel import llhelper
+ cpu = self.cpu
+ #
+ def func(c):
+ return chr(ord(c) + 1)
+ FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char))
+ func_ptr = llhelper(FPTR, func)
+ calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char)
+ res = self.execute_operation(rop.CALL,
+ [self.get_funcbox(cpu, func_ptr),
+ BoxInt(ord('A'))],
+ 'int', descr=calldescr)
+ assert res.value == ord('B')
+
def test_executor(self):
cpu = self.cpu
x = execute(cpu, rop.INT_ADD, [BoxInt(100), ConstInt(42)])
More information about the Pypy-commit
mailing list