[pypy-svn] r65663 - in pypy/branch/pyjitpl5-experiments/pypy/jit/backend: llvm test
arigo at codespeak.net
arigo at codespeak.net
Mon Jun 8 17:12:59 CEST 2009
Author: arigo
Date: Mon Jun 8 17:12:58 2009
New Revision: 65663
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py
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:
Arrays.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py Mon Jun 8 17:12:58 2009
@@ -7,7 +7,7 @@
from pypy.jit.metainterp import resoperation
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.backend.x86 import symbolic # xxx
-from pypy.jit.backend.llvm.runner import CallDescr, FieldDescr
+from pypy.jit.backend.llvm.runner import CallDescr, FieldDescr, ArrayDescr
# ____________________________________________________________
@@ -473,18 +473,8 @@
self.getptrarg(v_structure),
indices, 1, "")
lltype.free(indices, flavor='raw')
- if fielddescr.size < 0: # pointer field
- ty_val = self.cpu.ty_char_ptr
- ty = self.cpu.ty_char_ptr_ptr
- elif fielddescr.size == symbolic.get_size(lltype.Signed,
- self.cpu.translate_support_code):
- ty_val = self.cpu.ty_int
- ty = self.cpu.ty_int_ptr
- elif fielddescr.size == 1:
- ty_val = self.cpu.ty_char
- ty = self.cpu.ty_char_ptr
- else:
- raise BadSizeError
+ ty_val = self.cpu.types_by_index[fielddescr.size_index]
+ ty = self.cpu.types_ptr_by_index[fielddescr.size_index]
location = llvm_rffi.LLVMBuildBitCast(self.builder, location, ty, "")
return location, ty_val
@@ -492,6 +482,8 @@
loc, _ = self._generate_field_gep(op.args[0], op.descr)
self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
+ generate_GETFIELD_GC_PURE = generate_GETFIELD_GC
+
def generate_SETFIELD_GC(self, op):
loc, tyval = self._generate_field_gep(op.args[0], op.descr)
if tyval == self.cpu.ty_char_ptr:
@@ -571,14 +563,56 @@
self.getptrarg(op.args[0]),
self.cpu.const_null_charptr, "")
+ def generate_ARRAYLEN_GC(self, op):
+ arraydescr = op.descr
+ assert isinstance(arraydescr, ArrayDescr)
+ array = llvm_rffi.LLVMBuildBitCast(self.builder,
+ self.getptrarg(op.args[0]),
+ arraydescr.ty_array_ptr, "")
+ indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2,
+ flavor='raw')
+ indices[0] = self.cpu.const_zero
+ indices[1] = self.cpu.const_array_index_length
+ loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "")
+ lltype.free(indices, flavor='raw')
+ self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
+
+ def _generate_array_gep(self, v_array, v_index, arraydescr):
+ assert isinstance(arraydescr, ArrayDescr)
+ array = llvm_rffi.LLVMBuildBitCast(self.builder,
+ self.getptrarg(v_array),
+ arraydescr.ty_array_ptr, "")
+ indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3,
+ flavor='raw')
+ indices[0] = self.cpu.const_zero
+ indices[1] = self.cpu.const_array_index_array
+ indices[2] = self.getintarg(v_index)
+ location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "")
+ lltype.free(indices, flavor='raw')
+ ty_val = self.cpu.types_by_index[arraydescr.itemsize_index]
+ return location, ty_val
+
+ def generate_GETARRAYITEM_GC(self, op):
+ loc, _ = self._generate_array_gep(op.args[0], op.args[1], op.descr)
+ self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
+
+ generate_GETARRAYITEM_GC_PURE = generate_GETARRAYITEM_GC
+
+ def generate_SETARRAYITEM_GC(self, op):
+ loc, tyval = self._generate_array_gep(op.args[0], op.args[1], op.descr)
+ if tyval == self.cpu.ty_char_ptr:
+ value_ref = self.getptrarg(op.args[2])
+ elif tyval == self.cpu.ty_char:
+ value_ref = self.getchararg(op.args[2])
+ else:
+ value_ref = self.getintarg(op.args[2])
+ llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
+
# ____________________________________________________________
class MissingOperation(Exception):
pass
-class BadSizeError(Exception):
- pass
-
all_operations = {}
for _key, _value in rop.__dict__.items():
if 'A' <= _key <= 'Z':
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 Mon Jun 8 17:12:58 2009
@@ -123,6 +123,14 @@
rffi.UINT, # param count
rffi.INT], # flag: is_vararg
LLVMTypeRef)
+LLVMStructType = llexternal('LLVMStructType',
+ [rffi.CArrayPtr(LLVMTypeRef), # element types
+ rffi.UINT, # element count
+ rffi.INT], # flag: packed
+ LLVMTypeRef)
+LLVMArrayType = llexternal('LLVMArrayType', [LLVMTypeRef, # element type
+ rffi.UINT], # element count
+ LLVMTypeRef)
LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type
rffi.UINT], # address space
LLVMTypeRef)
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 Mon Jun 8 17:12:58 2009
@@ -18,6 +18,10 @@
SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1)
POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1)
+ SIZE_GCPTR = 0
+ SIZE_INT = 1
+ SIZE_CHAR = 2
+
def __init__(self, rtyper, stats=None, translate_support_code=False,
annmixlevel=None):
self.rtyper = rtyper
@@ -25,12 +29,19 @@
self.compiled_functions = []
self.fail_ops = []
self.in_out_args = []
- self._descr_caches = {}
+ self._descr_caches = {
+ ('array', self.SIZE_GCPTR): ArrayDescr(self.SIZE_GCPTR),
+ ('array', self.SIZE_INT): ArrayDescr(self.SIZE_INT),
+ ('array', self.SIZE_CHAR): ArrayDescr(self.SIZE_CHAR),
+ }
self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
if sys.maxint == 2147483647:
self.size_of_int = 4
else:
self.size_of_int = 8
+ basesize, _, ofs_length = symbolic.get_array_token(
+ lltype.GcArray(lltype.Signed), self.translate_support_code)
+ self._fixed_array_shape = basesize, ofs_length
def setup_once(self):
if not we_are_translated():
@@ -53,6 +64,41 @@
self.const_minint = self._make_const_int(-sys.maxint-1)
self.const_null_charptr = self._make_const(0, self.ty_char_ptr)
#
+ self.types_by_index = [self.ty_char_ptr, # SIZE_GCPTR
+ self.ty_int, # SIZE_INT
+ self.ty_char] # SIZE_CHAR
+ self.types_ptr_by_index = [self.ty_char_ptr_ptr, # SIZE_GCPTR
+ self.ty_int_ptr, # SIZE_INT
+ self.ty_char_ptr] # SIZE_CHAR
+ pad1 = self._fixed_array_shape[1]
+ pad2 = (self._fixed_array_shape[0] - self._fixed_array_shape[1]
+ - self.size_of_int)
+ self.const_array_index_length = self._make_const_int(pad1)
+ self.const_array_index_array = self._make_const_int(pad1 + 1 + pad2)
+ for i in range(len(self.types_by_index)):
+ # build the type "struct{pad1.., length, pad2.., array{type}}"
+ typeslist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef),
+ pad1+pad2+2, flavor='raw')
+ # add the first padding
+ for n in range(pad1):
+ typeslist[n] = self.ty_char
+ # add the length field
+ typeslist[pad1] = self.ty_int
+ # add the second padding
+ for n in range(pad1+1, pad1+1+pad2):
+ typeslist[n] = self.ty_char
+ # add the array field
+ typeslist[pad1+1+pad2] = llvm_rffi.LLVMArrayType(
+ self.types_by_index[i], 0)
+ # done
+ ty_array = llvm_rffi.LLVMStructType(typeslist,
+ pad1+pad2+2,
+ 1)
+ lltype.free(typeslist, flavor='raw')
+ ty_array_ptr = llvm_rffi.LLVMPointerType(ty_array, 0)
+ arraydescr = self._descr_caches['array', i]
+ arraydescr.ty_array_ptr = ty_array_ptr
+ #
arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0,
flavor='raw')
self.ty_func = llvm_rffi.LLVMFunctionType(self.ty_int, arglist, 0,
@@ -230,20 +276,38 @@
# indirect casting because the above doesn't work with ll2ctypes
return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x))
+ def _get_size_index(self, TYPE):
+ if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
+ return self.SIZE_GCPTR
+ else:
+ size = symbolic.get_size(TYPE, self.translate_support_code)
+ if size == symbolic.get_size(lltype.Signed,
+ self.translate_support_code):
+ return self.SIZE_INT
+ elif size == 1:
+ return self.SIZE_CHAR
+ else:
+ raise BadSizeError(S, fieldname, size)
+
def fielddescrof(self, S, fieldname):
try:
return self._descr_caches['field', S, fieldname]
except KeyError:
pass
- ofs, size = symbolic.get_field_token(S, fieldname,
- self.translate_support_code)
- if (isinstance(getattr(S, fieldname), lltype.Ptr) and
- getattr(S, fieldname).TO._gckind == 'gc'):
- size = -1
- descr = FieldDescr(ofs, size)
+ ofs, _ = symbolic.get_field_token(S, fieldname,
+ self.translate_support_code)
+ size_index = self._get_size_index(getattr(S, fieldname))
+ descr = FieldDescr(ofs, size_index)
self._descr_caches['field', S, fieldname] = descr
return descr
+ def arraydescrof(self, A):
+ basesize, _, ofs_length = symbolic.get_array_token(A,
+ self.translate_support_code)
+ assert self._fixed_array_shape == (basesize, ofs_length)
+ itemsize_index = self._get_size_index(A.OF)
+ return self._descr_caches['array', itemsize_index]
+
def calldescrof(self, FUNC, ARGS, RESULT):
try:
return self._descr_caches['call', ARGS, RESULT]
@@ -317,9 +381,15 @@
class FieldDescr(AbstractDescr):
- def __init__(self, offset, size):
+ def __init__(self, offset, size_index):
self.offset = offset
- self.size = size # set to -1 to mark a pointer field
+ self.size_index = size_index # index in cpu.types_by_index
+
+class ArrayDescr(AbstractDescr):
+ def __init__(self, itemsize_index):
+ self.itemsize_index = itemsize_index # index in cpu.types_by_index
+ self.ty_array_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO)
+ # ^^^ set by setup_once()
class CallDescr(AbstractDescr):
def __init__(self, ty_function_ptr, result_mask):
@@ -329,5 +399,8 @@
# ____________________________________________________________
+class BadSizeError(Exception):
+ pass
+
import pypy.jit.metainterp.executor
pypy.jit.metainterp.executor.make_execute_list(LLVMCPU)
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 Mon Jun 8 17:12:58 2009
@@ -1,5 +1,5 @@
-import sys, random
+import py, sys, random
from pypy.jit.metainterp.history import (BoxInt, Box, BoxPtr, TreeLoop,
ConstInt, ConstPtr, BoxObj,
ConstObj)
@@ -384,6 +384,55 @@
r = self.execute_operation(rop.OONONNULL, [null_box], 'int')
assert r.value == 0
+ def test_array(self):
+ a_box, A = self.alloc_array_of(lltype.Signed, 342)
+ arraydescr = self.cpu.arraydescrof(A)
+ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
+ 'int', descr=arraydescr)
+ assert r.value == 342
+ r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
+ BoxInt(7441)],
+ 'void', descr=arraydescr)
+ assert r is None
+ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
+ 'int', descr=arraydescr)
+ assert r.value == 7441
+ #
+ a_box, A = self.alloc_array_of(lltype.Char, 11)
+ arraydescr = self.cpu.arraydescrof(A)
+ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
+ 'int', descr=arraydescr)
+ assert r.value == 11
+ r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(4),
+ BoxInt(150)],
+ 'void', descr=arraydescr)
+ assert r is None
+ r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(3),
+ BoxInt(160)],
+ 'void', descr=arraydescr)
+ assert r is None
+ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(4)],
+ 'int', descr=arraydescr)
+ assert r.value == 150
+ r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(3)],
+ 'int', descr=arraydescr)
+ assert r.value == 160
+ #
+ if isinstance(A, lltype.GcArray):
+ A = lltype.Ptr(A)
+ b_box, B = self.alloc_array_of(A, 3)
+ arraydescr = self.cpu.arraydescrof(B)
+ r = self.execute_operation(rop.ARRAYLEN_GC, [b_box],
+ 'int', descr=arraydescr)
+ assert r.value == 3
+ r = self.execute_operation(rop.SETARRAYITEM_GC, [b_box, BoxInt(1),
+ a_box],
+ 'void', descr=arraydescr)
+ assert r is None
+ r = self.execute_operation(rop.GETARRAYITEM_GC, [b_box, BoxInt(1)],
+ 'ptr', descr=arraydescr)
+ assert r.value == a_box.value
+
class LLtypeBackendTest(BaseBackendTest):
@@ -432,6 +481,13 @@
def null_instance(self):
return BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
+ def alloc_array_of(self, ITEM, length):
+ cpu = self.cpu
+ A = lltype.GcArray(ITEM)
+ a = lltype.malloc(A, length)
+ a_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, a))
+ return a_box, A
+
def test_casts(self):
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -486,3 +542,6 @@
def null_instance(self):
return BoxObj(ootype.NULL)
+
+ def alloc_array_of(self, ITEM, length):
+ py.test.skip("implement me")
More information about the Pypy-commit
mailing list