[pypy-svn] r61936 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph metainterp metainterp/test

fijal at codespeak.net fijal at codespeak.net
Sun Feb 15 14:50:20 CET 2009


Author: fijal
Date: Sun Feb 15 14:50:17 2009
New Revision: 61936

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py
Log:
support for insert (only for virtual lists, otherwise explodes)


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	Sun Feb 15 14:50:17 2009
@@ -83,9 +83,13 @@
     'strlen'          : (('ptr',), 'int'),
     'strgetitem'      : (('ptr', 'int'), 'int'),
     'strsetitem'      : (('ptr', 'int', 'int'), None),
-    'getitem'         : (('ptr', 'ptr', 'int'), 'int'),
-    'setitem'         : (('ptr', 'ptr', 'int', 'int'), None),
-    'newlist'         : (('ptr', 'varargs'), 'ptr'),
+    'getitem'         : (('void', 'ptr', 'int'), 'int'),
+    'setitem'         : (('void', 'ptr', 'int', 'int'), None),
+    'newlist'         : (('void', 'varargs'), 'ptr'),
+    'append'          : (('void', 'ptr', 'int'), None),
+    'insert'          : (('void', 'ptr', 'int', 'int'), None),
+    'pop'             : (('void', 'ptr',), 'int'),
+    'len'             : (('void', 'ptr',), 'int'),
 }
 
 # ____________________________________________________________
@@ -158,6 +162,8 @@
             tp = "int"
     if tp == 'int':
         return str(x)
+    elif tp == 'void':
+        return ''
     elif tp == 'ptr':
         if not x:
             return '(* None)'
@@ -756,11 +762,18 @@
     op_call_ptr = do_call
     op_call_void = do_call
 
-    def op_getitem(self, ll_getitem, lst, item):
-        return self.do_call(ll_getitem, lst, item)
+    def op_listop_return(self, ll_func, *args):
+        return self.do_call(ll_func, *args)
 
-    def op_setitem(self, ll_setitem, lst, item, val):
-        self.do_call(ll_setitem, lst, item, val)
+    def op_listop(self, ll_func, *args):
+        self.do_call(ll_func, *args)
+
+    op_getitem = op_listop_return
+    op_setitem = op_listop
+    op_append = op_listop
+    op_insert = op_listop
+    op_pop = op_listop_return
+    op_len = op_listop_return
 
     def op_newlist(self, ll_newlist, lgt, default_val=None):
         res = self.do_call(ll_newlist, lgt)
@@ -772,8 +785,12 @@
             else:
                 default_val = lltype.nullptr(TP.TO)
         if default_val is not None:
-            for i in range(len(res)):
-                res[i] = default_val
+            if hasattr(res, 'items'):
+                items = res.items
+            else:
+                items = res
+            for i in range(len(items)):
+                items[i] = default_val
         return res
 
     def op_cast_int_to_ptr(self, i):

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Sun Feb 15 14:50:17 2009
@@ -19,11 +19,12 @@
 
 class ListDescr(BuiltinDescr):
     def __init__(self, getfunc, setfunc, malloc_func, append_func,
-                 pop_func, len_func, tp):
+                 pop_func, insert_func, len_func, tp):
         self.setfunc     = setfunc
         self.getfunc     = getfunc
         self.malloc_func = malloc_func
         self.append_func = append_func
+        self.insert_func = insert_func
         self.pop_func    = pop_func
         self.len_func    = len_func
         self.tp          = tp
@@ -170,6 +171,8 @@
                                                         [TP, OF], lltype.Void)
                 pop_func, _ = support.builtin_func_for_spec(rtyper, 'list.pop',
                                                             [TP], OF)
+                insert_func, _ = support.builtin_func_for_spec(rtyper,
+                      'list.insert', [TP, lltype.Signed, OF], lltype.Void)
             if isinstance(OF, lltype.Number):
                 tp = "int"
             else:
@@ -180,13 +183,14 @@
                                history.ConstAddr(malloc_func.value, self.cpu),
                                history.ConstAddr(append_func.value, self.cpu),
                                history.ConstAddr(pop_func.value, self.cpu),
+                               history.ConstAddr(insert_func.value, self.cpu),
                                history.ConstAddr(len_func.value, self.cpu),
                                tp)
             else:
                 ld = ListDescr(history.ConstAddr(getfunc.value, self.cpu),
                                history.ConstAddr(setfunc.value, self.cpu),
                                history.ConstAddr(malloc_func.value, self.cpu),
-                               None, None,
+                               None, None, None,
                                history.ConstAddr(len_func.value, self.cpu),
                                tp)
             self.list_cache[TP.TO] = ld
@@ -658,6 +662,8 @@
                 opname = 'pop'
             elif oopspec_name == 'list.len':
                 opname = 'len'
+            elif oopspec_name == 'list.insert':
+                opname = 'insert'
             else:
                 raise NotImplementedError("not supported %s" % oopspec_name)
             self.emit(opname)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	Sun Feb 15 14:50:17 2009
@@ -276,7 +276,14 @@
             instnode.origfields[field] = fieldnode
         self.nodes[box] = fieldnode
         if self.first_escaping_op:
-            instnode.expanded_fields[field] = None        
+            instnode.expanded_fields[field] = None
+
+    def find_nodes_insert(self, instnode, field, fieldnode):
+        for ofs, node in instnode.curfields.items():
+            if ofs >= field:
+                instnode.curfields[ofs + 1] = node
+        instnode.curfields[field] = fieldnode
+        self.dependency_graph.append((instnode, fieldnode))
         
     def find_nodes(self):
         # Steps (1) and (2)
@@ -350,6 +357,16 @@
                 self.find_nodes_setfield(instnode, field,
                                          self.getnode(op.args[2]))
                 continue
+            elif opname == 'insert':
+                instnode = self.getnode(op.args[1])
+                assert isinstance(instnode.cls.source, ListDescr)
+                assert instnode.known_length != -1
+                fieldbox = self.getsource(op.args[2])
+                assert isinstance(fieldbox, Const) or fieldbox.const
+                field = fieldbox.getint()
+                self.find_nodes_insert(instnode, field,
+                                       self.getnode(op.args[3]))
+                continue
             elif opname == 'pop':
                 instnode = self.getnode(op.args[1])
                 assert isinstance(instnode.cls.source, ListDescr)
@@ -534,6 +551,13 @@
             instnode.dirtyfields[ofs] = self.nodes[valuebox]
             # we never perform this operation here, note
 
+    def optimize_insert(self, instnode, field, valuenode, valuebox):
+        assert instnode.virtual
+        for ofs, node in instnode.curfields.items():
+            if ofs >= field:
+                instnode.curfields[ofs + 1] = node
+        instnode.curfields[field] = valuenode
+
     def optimize_loop(self):
         self.ready_results = {}
         newoperations = []
@@ -661,6 +685,12 @@
                 assert ofs != -1
                 self.optimize_setfield(instnode, ofs, valuenode, op.args[2])
                 continue
+            elif opname == 'insert':
+                instnode = self.nodes[op.args[1]]
+                ofs = self.getsource(op.args[2]).getint()
+                valuenode = self.nodes[op.args[3]]
+                self.optimize_insert(instnode, ofs, valuenode, op.args[3])
+                continue
             elif opname == 'pop':
                 instnode = self.nodes[op.args[1]]
                 instnode.known_length -= 1

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Sun Feb 15 14:50:17 2009
@@ -412,6 +412,11 @@
         self.execute_with_exc('append', args, 'void')
 
     @arguments("builtin", "varargs")
+    def opimpl_insert(self, descr, varargs):
+        args = [descr.insert_func] + varargs
+        self.execute_with_exc('insert', args, 'void')
+
+    @arguments("builtin", "varargs")
     def opimpl_pop(self, descr, varargs):
         args = [descr.pop_func] + varargs
         self.execute_with_exc('pop', args, descr.tp)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py	Sun Feb 15 14:50:17 2009
@@ -9,7 +9,8 @@
 
     def check_all_virtualized(self):
         self.check_loops(new=0, newlist=0,
-                         getitem=0, setitem=0, append=0, pop=0, len=0)
+                         getitem=0, setitem=0, append=0, pop=0, len=0,
+                         insert=0)
 
     def test_simple_array(self):
         jitdriver = JitDriver(greens = [], reds = ['n'])
@@ -95,15 +96,19 @@
         self.check_all_virtualized()
 
     def test_insert(self):
-        py.test.skip("XXX")
+        jitdriver = JitDriver(greens = [], reds = ['n'])
         def f(n):
             while n > 0:
+                jitdriver.can_enter_jit(n=n)
+                jitdriver.jit_merge_point(n=n)
                 lst = [1, 2, 3]
                 lst.insert(0, n)
-                n = lst[0] - 10
+                n = lst[0] - 1
+                lst.pop()
+                # last pop is needed, otherwise it won't work
             return n
-        res = self.meta_interp(f, [33], exceptions=False)
-        assert res == -7
+        res = self.meta_interp(f, [33])
+        assert res == f(33)
         self.check_all_virtualized()
 
     def test_list_escapes(self):



More information about the Pypy-commit mailing list