[pypy-svn] r74667 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Sat May 22 10:40:56 CEST 2010
Author: arigo
Date: Sat May 22 10:40:55 2010
New Revision: 74667
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_list.py
Log:
Resizable lists.
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py Sat May 22 10:40:55 2010
@@ -298,10 +298,13 @@
prepare = self._handle_virtual_ref_call
else:
prepare = self.prepare_builtin_call
- op1 = prepare(op, oopspec_name, args)
+ try:
+ op1 = prepare(op, oopspec_name, args)
+ except NotSupported:
+ op1 = op
# If the resulting op1 is still a direct_call, turn it into a
# residual_call.
- if op1 is None or op1.opname == 'direct_call':
+ if op1.opname == 'direct_call':
op1 = self.handle_residual_call(op1 or op)
return op1
@@ -688,6 +691,10 @@
# Lists.
def _handle_list_call(self, op, oopspec_name, args):
+ """Try to transform the call to a list-handling helper.
+ If no transformation is available, raise NotSupported
+ (in which case the original call is written as a residual call).
+ """
if oopspec_name.startswith('new'):
LIST = deref(op.result.concretetype)
else:
@@ -696,20 +703,25 @@
assert resizable == (not isinstance(LIST, lltype.GcArray))
if resizable:
prefix = 'do_resizable_'
+ ARRAY = LIST.items.TO
+ if self._array_of_voids(ARRAY):
+ raise NotSupported("resizable lists of voids")
+ descrs = (self.cpu.arraydescrof(ARRAY),
+ self.cpu.fielddescrof(LIST, 'length'),
+ self.cpu.fielddescrof(LIST, 'items'),
+ self.cpu.sizeof(LIST))
else:
prefix = 'do_fixed_'
if self._array_of_voids(LIST):
- return None # arrays of voids: not supported
+ raise NotSupported("fixed lists of voids")
arraydescr = self.cpu.arraydescrof(LIST)
descrs = (arraydescr,)
#
try:
meth = getattr(self, prefix + oopspec_name.replace('.', '_'))
except AttributeError:
- return None
- else:
- return meth(op, args, *descrs)
-
+ raise NotSupported(prefix + oopspec_name)
+ return meth(op, args, *descrs)
def _get_list_nonneg_canraise_flags(self, op):
# xxx break of abstraction:
@@ -731,7 +743,7 @@
def _prepare_list_getset(self, op, descr, args, checkname):
non_negative, can_raise = self._get_list_nonneg_canraise_flags(op)
if can_raise:
- return None, None
+ raise NotSupported("list operation can raise")
if non_negative:
return args[1], []
else:
@@ -741,19 +753,24 @@
descr, args[1]], v_posindex)
return v_posindex, [op]
- # ---------- fixed lists ----------
-
- def do_fixed_newlist(self, op, args, arraydescr):
- # normalize number of arguments
- if len(args) < 1:
- args.append(Constant(0, lltype.Signed))
+ def _get_initial_newlist_length(self, op, args):
+ # normalize number of arguments to the 'newlist' function
if len(args) > 1:
- v_default = args[1]
+ v_default = args[1] # initial value: must be 0 or NULL
ARRAY = deref(op.result.concretetype)
if (not isinstance(v_default, Constant) or
v_default.value != arrayItem(ARRAY)._defl()):
- return None # variable or non-null initial value
- return SpaceOperation('new_array', [arraydescr, args[0]], op.result)
+ raise NotSupported("variable or non-null initial value")
+ if len(args) >= 1:
+ return args[0]
+ else:
+ return Constant(0, lltype.Signed) # length: default to 0
+
+ # ---------- fixed lists ----------
+
+ def do_fixed_newlist(self, op, args, arraydescr):
+ v_length = self._get_initial_newlist_length(op, args)
+ return SpaceOperation('new_array', [arraydescr, v_length], op.result)
def do_fixed_list_len(self, op, args, arraydescr):
return SpaceOperation('arraylen_gc', [args[0], arraydescr], op.result)
@@ -763,8 +780,6 @@
def do_fixed_list_getitem(self, op, args, arraydescr, pure=False):
v_index, extraop = self._prepare_list_getset(op, arraydescr, args,
'check_neg_index')
- if v_index is None:
- return None
extra = getkind(op.result.concretetype)[0]
if pure:
extra = 'pure_' + extra
@@ -778,8 +793,6 @@
def do_fixed_list_setitem(self, op, args, arraydescr):
v_index, extraop = self._prepare_list_getset(op, arraydescr, args,
'check_neg_index')
- if v_index is None:
- return None
kind = getkind(op.args[2].concretetype)[0]
op = SpaceOperation('setarrayitem_gc_%s' % kind,
[args[0], arraydescr, v_index, args[2]], None)
@@ -793,7 +806,38 @@
# ---------- resizable lists ----------
- # xxx
+ def do_resizable_newlist(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ v_length = self._get_initial_newlist_length(op, args)
+ return SpaceOperation('newlist',
+ [structdescr, lengthdescr, itemsdescr,
+ arraydescr, v_length],
+ op.result)
+
+ def do_resizable_list_getitem(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ v_index, extraop = self._prepare_list_getset(op, lengthdescr, args,
+ 'check_resizable_neg_index')
+ kind = getkind(op.result.concretetype)[0]
+ op = SpaceOperation('getlistitem_gc_%s' % kind,
+ [args[0], itemsdescr, arraydescr, v_index],
+ op.result)
+ return extraop + [op]
+
+ def do_resizable_list_setitem(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ v_index, extraop = self._prepare_list_getset(op, lengthdescr, args,
+ 'check_resizable_neg_index')
+ kind = getkind(op.args[2].concretetype)[0]
+ op = SpaceOperation('setlistitem_gc_%s' % kind,
+ [args[0], itemsdescr, arraydescr,
+ v_index, args[2]], None)
+ return extraop + [op]
+
+ def do_resizable_list_len(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ return SpaceOperation('getfield_gc_i',
+ [args[0], lengthdescr], op.result)
# ----------
# VirtualRefs.
@@ -810,6 +854,9 @@
# ____________________________________________________________
+class NotSupported(Exception):
+ pass
+
def _with_prefix(prefix):
result = {}
for name in dir(Transformer):
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_list.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_list.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_list.py Sat May 22 10:40:55 2010
@@ -2,7 +2,7 @@
from pypy.translator.unsimplify import varoftype
from pypy.objspace.flow.model import Constant, SpaceOperation
-from pypy.jit.codewriter.jtransform import Transformer
+from pypy.jit.codewriter.jtransform import Transformer, NotSupported
from pypy.jit.codewriter.flatten import GraphFlattener
from pypy.jit.codewriter.format import assert_format
from pypy.jit.codewriter.test.test_flatten import fake_regallocs
@@ -11,6 +11,10 @@
# ____________________________________________________________
FIXEDLIST = lltype.Ptr(lltype.GcArray(lltype.Signed))
+VARLIST = lltype.Ptr(lltype.GcStruct('VARLIST',
+ ('length', lltype.Signed),
+ ('items', FIXEDLIST),
+ adtmeths={"ITEM": lltype.Signed}))
class FakeCPU:
class arraydescrof(AbstractDescr):
@@ -18,6 +22,17 @@
self.ARRAY = ARRAY
def __repr__(self):
return '<ArrayDescr>'
+ class fielddescrof(AbstractDescr):
+ def __init__(self, STRUCT, fieldname):
+ self.STRUCT = STRUCT
+ self.fieldname = fieldname
+ def __repr__(self):
+ return '<FieldDescr %s>' % self.fieldname
+ class sizeof(AbstractDescr):
+ def __init__(self, STRUCT):
+ self.STRUCT = STRUCT
+ def __repr__(self):
+ return '<SizeDescr>'
class FakeCallControl:
class getcalldescr(AbstractDescr):
@@ -40,10 +55,12 @@
op = SpaceOperation('direct_call',
[Constant("myfunc", lltype.Void)] + args,
v_result)
- oplist = tr._handle_list_call(op, oopspec_name, args)
- if expected is None:
- assert oplist is None
+ try:
+ oplist = tr._handle_list_call(op, oopspec_name, args)
+ except NotSupported:
+ assert expected is NotSupported
else:
+ assert expected is not NotSupported
assert oplist is not None
flattener = GraphFlattener(None, fake_regallocs())
if not isinstance(oplist, list):
@@ -53,6 +70,7 @@
assert_format(flattener.ssarepr, expected)
# ____________________________________________________________
+# Fixed lists
def test_newlist():
builtin_test('newlist', [], FIXEDLIST,
@@ -65,9 +83,11 @@
Constant(0, lltype.Signed)], FIXEDLIST,
"""new_array <ArrayDescr>, $5 -> %r0""")
builtin_test('newlist', [Constant(5, lltype.Signed),
- Constant(1, lltype.Signed)], FIXEDLIST, None)
+ Constant(1, lltype.Signed)], FIXEDLIST,
+ NotSupported)
builtin_test('newlist', [Constant(5, lltype.Signed),
- varoftype(lltype.Signed)], FIXEDLIST, None)
+ varoftype(lltype.Signed)], FIXEDLIST,
+ NotSupported)
def test_fixed_ll_arraycopy():
builtin_test('list.ll_arraycopy',
@@ -94,7 +114,7 @@
""")
builtin_test('list.getitem/CANRAISE',
[varoftype(FIXEDLIST), varoftype(lltype.Signed)],
- lltype.Signed, None)
+ lltype.Signed, NotSupported)
def test_fixed_getitem_foldable():
builtin_test('list.getitem_foldable/NONNEG',
@@ -110,7 +130,7 @@
""")
builtin_test('list.getitem_foldable/CANRAISE',
[varoftype(FIXEDLIST), varoftype(lltype.Signed)],
- lltype.Signed, None)
+ lltype.Signed, NotSupported)
def test_fixed_setitem():
builtin_test('list.setitem/NONNEG', [varoftype(FIXEDLIST),
@@ -129,7 +149,7 @@
builtin_test('list.setitem/CANRAISE', [varoftype(FIXEDLIST),
varoftype(lltype.Signed),
varoftype(lltype.Signed)],
- lltype.Void, None)
+ lltype.Void, NotSupported)
def test_fixed_len():
builtin_test('list.len', [varoftype(FIXEDLIST)], lltype.Signed,
@@ -139,17 +159,67 @@
builtin_test('list.len_foldable', [varoftype(FIXEDLIST)], lltype.Signed,
"""arraylen_gc %r0, <ArrayDescr> -> %i0""")
+# ____________________________________________________________
+# Resizable lists
+
def test_resizable_newlist():
- xxx
+ alldescrs = ("<SizeDescr>, <FieldDescr length>,"
+ " <FieldDescr items>, <ArrayDescr>")
+ builtin_test('newlist', [], VARLIST,
+ """newlist """+alldescrs+""", $0 -> %r0""")
+ builtin_test('newlist', [Constant(5, lltype.Signed)], VARLIST,
+ """newlist """+alldescrs+""", $5 -> %r0""")
+ builtin_test('newlist', [varoftype(lltype.Signed)], VARLIST,
+ """newlist """+alldescrs+""", %i0 -> %r0""")
+ builtin_test('newlist', [Constant(5, lltype.Signed),
+ Constant(0, lltype.Signed)], VARLIST,
+ """newlist """+alldescrs+""", $5 -> %r0""")
+ builtin_test('newlist', [Constant(5, lltype.Signed),
+ Constant(1, lltype.Signed)], VARLIST,
+ NotSupported)
+ builtin_test('newlist', [Constant(5, lltype.Signed),
+ varoftype(lltype.Signed)], VARLIST,
+ NotSupported)
def test_resizable_getitem():
- xxx
+ builtin_test('list.getitem/NONNEG',
+ [varoftype(VARLIST), varoftype(lltype.Signed)],
+ lltype.Signed, """
+ getlistitem_gc_i %r0, <FieldDescr items>, <ArrayDescr>, %i0 -> %i1
+ """)
+ builtin_test('list.getitem/NEG',
+ [varoftype(VARLIST), varoftype(lltype.Signed)],
+ lltype.Signed, """
+ check_resizable_neg_index %r0, <FieldDescr length>, %i0 -> %i1
+ getlistitem_gc_i %r0, <FieldDescr items>, <ArrayDescr>, %i1 -> %i2
+ """)
+ builtin_test('list.getitem/CANRAISE',
+ [varoftype(VARLIST), varoftype(lltype.Signed)],
+ lltype.Signed, NotSupported)
def test_resizable_setitem():
- xxx
+ builtin_test('list.setitem/NONNEG', [varoftype(VARLIST),
+ varoftype(lltype.Signed),
+ varoftype(lltype.Signed)],
+ lltype.Void, """
+ setlistitem_gc_i %r0, <FieldDescr items>, <ArrayDescr>, %i0, %i1
+ """)
+ builtin_test('list.setitem/NEG', [varoftype(VARLIST),
+ varoftype(lltype.Signed),
+ varoftype(lltype.Signed)],
+ lltype.Void, """
+ check_resizable_neg_index %r0, <FieldDescr length>, %i0 -> %i1
+ setlistitem_gc_i %r0, <FieldDescr items>, <ArrayDescr>, %i1, %i2
+ """)
+ builtin_test('list.setitem/CANRAISE', [varoftype(VARLIST),
+ varoftype(lltype.Signed),
+ varoftype(lltype.Signed)],
+ lltype.Void, NotSupported)
def test_resizable_len():
- xxx
+ builtin_test('list.len', [varoftype(VARLIST)], lltype.Signed,
+ """getfield_gc_i %r0, <FieldDescr length> -> %i0""")
def test_resizable_unsupportedop():
- builtin_test('list.foobar', [varoftype(VARLIST)], lltype.Signed, None)
+ builtin_test('list.foobar', [varoftype(VARLIST)], lltype.Signed,
+ NotSupported)
More information about the Pypy-commit
mailing list