[pypy-svn] pypy jit-short_from_state: getfield support

hakanardo commits-noreply at bitbucket.org
Sat Apr 16 13:40:55 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r43398:93feea3e67e6
Date: 2011-04-16 13:38 +0200
http://bitbucket.org/pypy/pypy/changeset/93feea3e67e6/

Log:	getfield support

diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -256,58 +256,63 @@
 
         # This loop is equivalent to the main optimization loop in
         # Optimizer.propagate_all_forward
+        jumpop = None
         for newop in loop_operations:
             newop = inliner.inline_op(newop, clone=False)
             if newop.getopnum() == rop.JUMP:
                 values = [self.getvalue(arg) for arg in newop.getarglist()]
                 newop.initarglist(virtual_state.make_inputargs(values))
+                jumpop = newop
+                break
 
             #self.optimizer.first_optimization.propagate_forward(newop)
             self.optimizer.send_extra_operation(newop)
-
-        # Remove jump to make sure forced code are placed before it
-        newoperations = self.optimizer.newoperations
-        jmp = newoperations[-1]
-        assert jmp.getopnum() == rop.JUMP
-        self.optimizer.newoperations = newoperations[:-1]
+        assert jumpop
 
         self.boxes_created_this_iteration = {}
-        jumpargs = jmp.getarglist()
+        jumpargs = jumpop.getarglist()
 
         self.short_inliner = Inliner(inputargs, jumpargs)
         short = []
 
-        # FIXME: Should also loop over operations added by forcing things in this loop
-        for op in newoperations: 
+        i = j = 0
+        while i < len(self.optimizer.newoperations):
+            op = self.optimizer.newoperations[i]
             self.boxes_created_this_iteration[op.result] = True
             args = op.getarglist()
             if op.is_guard():
                 args = args + op.getfailargs()
             
             for a in args:
-                self.import_box(a, inputargs, short, short_jumpargs, jumpargs)
+                self.import_box(a, inputargs, short, short_jumpargs,
+                                jumpargs, True)
+            i += 1
 
-        jmp.initarglist(jumpargs)
-        self.optimizer.newoperations.append(jmp)
+            if i == len(self.optimizer.newoperations):
+                while j < len(jumpargs):
+                    a = jumpargs[j]
+                    self.import_box(a, inputargs, short, short_jumpargs,
+                                    jumpargs, True)
+                    j += 1
+
+        jumpop.initarglist(jumpargs)
+        self.optimizer.send_extra_operation(jumpop)
         short.append(ResOperation(rop.JUMP, short_jumpargs, None))
         return inputargs, short
 
-    def import_box(self, box, inputargs, short, short_jumpargs, jumpargs):
+    def import_box(self, box, inputargs, short, short_jumpargs,
+                   jumpargs, extend_inputargs):
         if isinstance(box, Const) or box in inputargs:
             return
         if box in self.boxes_created_this_iteration:
             return
 
         short_op = self.short_boxes[box]
-        import pdb; pdb.set_trace()
-        
         for a in short_op.getarglist():
-            self.import_box(a, inputargs, short, short_jumpargs, jumpargs)
+            self.import_box(a, inputargs, short, short_jumpargs, jumpargs, False)
         short.append(short_op)
-        short_jumpargs.append(short_op.result)
         newop = self.short_inliner.inline_op(short_op)
         self.optimizer.send_extra_operation(newop)
-        inputargs.append(box)
         if newop.is_ovf():
             # FIXME: ensure that GUARD_OVERFLOW:ed ops not end up here
             guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
@@ -317,10 +322,13 @@
             self.optimizer.send_extra_operation(guard)
             assert self.optimizer.newoperations[-1] is not guard
 
-        box = newop.result
-        if box in self.optimizer.values:
-            box = self.optimizer.values[box].force_box()
-        jumpargs.append(box)
+        if extend_inputargs:
+            short_jumpargs.append(short_op.result)
+            inputargs.append(box)
+            box = newop.result
+            if box in self.optimizer.values:
+                box = self.optimizer.values[box].force_box()
+            jumpargs.append(box)
         
     def sameop(self, op1, op2):
         if op1.getopnum() != op2.getopnum():

diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -1673,6 +1673,24 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_duplicate_getfield_2(self):
+        ops = """
+        [p1, p2, i0]
+        i1 = getfield_gc(p1, descr=valuedescr)
+        i2 = getfield_gc(p2, descr=valuedescr)
+        i3 = getfield_gc(p1, descr=valuedescr)
+        i4 = getfield_gc(p2, descr=valuedescr)
+        i5 = int_add(i3, i4)
+        i6 = int_add(i0, i5)
+        jump(p1, p2, i6)
+        """
+        expected = """
+        [p1, p2, i0, i5]
+        i6 = int_add(i0, i5)
+        jump(p1, p2, i6, i5)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_getfield_after_setfield(self):
         ops = """
         [p1, i1]

diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -99,6 +99,14 @@
             cf._cached_fields[structvalue2] = fieldvalue2
         return cf
 
+    def produce_potential_short_preamble_ops(self, potential_ops, descr):
+        for structvalue, fieldvalue in self._cached_fields.iteritems():
+            result = fieldvalue.get_key_box()
+            potential_ops[result] = ResOperation(rop.GETFIELD_GC,
+                                                 [structvalue.get_key_box()],
+                                                 result,
+                                                 descr)
+
 
 class CachedArrayItems(object):
     def __init__(self):
@@ -129,7 +137,7 @@
             self.force_all_lazy_setfields()
         else:
             assert 0   # was: new.lazy_setfields = self.lazy_setfields
-        
+
         for descr, d in self.cached_fields.items():
             new.cached_fields[descr] = d.get_cloned(optimizer, valuemap)
 
@@ -153,6 +161,10 @@
 
         return new
 
+    def produce_potential_short_preamble_ops(self, potential_ops):        
+        for descr, d in self.cached_fields.items():
+            d.produce_potential_short_preamble_ops(potential_ops, descr)
+
     def clean_caches(self):
         del self._lazy_setfields[:]
         self.cached_fields.clear()


More information about the Pypy-commit mailing list