[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