Author: Hakan Ardo <[email protected]>
Branch: jit-short_from_state
Changeset: r45984:f4b02767e294
Date: 2011-07-24 21:22 +0200
http://bitbucket.org/pypy/pypy/changeset/f4b02767e294/

Log:    generalize the renaming of result boxes on conflicts to support all
        kind of ops in the short preamble, not only setfields

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
@@ -125,15 +125,9 @@
             if op and structvalue in self._cached_fields:
                 if op.getopnum() == rop.SETFIELD_GC:
                     result = op.getarg(1)
-                    if result in shortboxes.potential_ops and \
-                           shortboxes.potential_ops[result] is None:
-                        newresult = result.clonebox()
-                        optimizer.make_equal_to(newresult, 
optimizer.getvalue(result))
-                        result = newresult
-                        # XXX this will not allow for chains of operations
                     getop = ResOperation(rop.GETFIELD_GC, [op.getarg(0)],
                                          result, op.getdescr())
-                    shortboxes.add_potential(getop)
+                    getop = shortboxes.add_potential(getop)
                     self._cached_fields_getfield_op[structvalue] = getop
                     self._cached_fields[structvalue] = 
optimizer.getvalue(result)
                 elif op.result is not None:
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py 
b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -899,8 +899,6 @@
         setfield_gc(p3, i2, descr=nextdescr)
         # XXX: VIRTUALHEAP (see above)
         i3 = getfield_gc(p3, descr=nextdescr)
-        i7 = int_is_true(i3)
-        guard_true(i7) []
         jump(p3, i3)
         """
         self.optimize_loop(ops, expected, preamble)
@@ -2009,15 +2007,14 @@
         guard_true(i3) []
         i4 = int_neg(i2)
         setfield_gc(p1, i2, descr=valuedescr)
-        jump(p1, i1, i2, i4)
-        """
-        expected = """
-        [p1, i1, i2, i4]
+        jump(p1, i1, i2, i4, i4)
+        """
+        expected = """
+        [p1, i1, i2, i4, i5]
         setfield_gc(p1, i1, descr=valuedescr)
         guard_true(i4) []
-        i5 = int_neg(i2)
         setfield_gc(p1, i2, descr=valuedescr)
-        jump(p1, i1, i2, i5)
+        jump(p1, i1, i2, i5, i5)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -2040,15 +2037,14 @@
         i4 = int_neg(i2)
         setfield_gc(p1, NULL, descr=nextdescr)
         escape()
-        jump(p1, i2, i4)
-        """
-        expected = """
-        [p1, i2, i4]
+        jump(p1, i2, i4, i4)
+        """
+        expected = """
+        [p1, i2, i4, i5]
         guard_true(i4) [p1]
-        i5 = int_neg(i2)
         setfield_gc(p1, NULL, descr=nextdescr)
         escape()
-        jump(p1, i2, i5)
+        jump(p1, i2, i5, i5)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -2070,15 +2066,14 @@
         i4 = int_neg(i2)
         setfield_gc(p1, NULL, descr=nextdescr)
         escape()
-        jump(p1, i2, i4)
-        """
-        expected = """
-        [p1, i2, i4]
+        jump(p1, i2, i4, i4)
+        """
+        expected = """
+        [p1, i2, i4, i5]
         guard_true(i4) [i2, p1]
-        i5 = int_neg(i2)
         setfield_gc(p1, NULL, descr=nextdescr)
         escape()
-        jump(p1, i2, i5)
+        jump(p1, i2, i5, i5)
         """
         self.optimize_loop(ops, expected)
 
@@ -2094,15 +2089,22 @@
         setfield_gc(p1, i2, descr=valuedescr)
         jump(p1, i1, i2, i4)
         """
-        preamble = ops
-        expected = """
-        [p1, i1, i2, i4]
+        preamble = """
+        [p1, i1, i2, i3]
+        setfield_gc(p1, i1, descr=valuedescr)
+        i5 = int_eq(i3, 5)
+        guard_true(i5) []
+        i4 = int_neg(i2)
+        setfield_gc(p1, i2, descr=valuedescr)
+        jump(p1, i1, i2, i4, i4)
+        """
+        expected = """
+        [p1, i1, i2, i4, i7]
         setfield_gc(p1, i1, descr=valuedescr)
         i5 = int_eq(i4, 5)
         guard_true(i5) []
-        i7 = int_neg(i2)
         setfield_gc(p1, i2, descr=valuedescr)
-        jump(p1, i1, i2, i7)
+        jump(p1, i1, i2, i7, i7)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -2323,13 +2325,12 @@
         jump(p1, i2, i4, p4)
         """
         expected = """
-        [p1, i2, i4, p4]
+        [p1, i2, i4, p4, i5]
         guard_true(i4) [p1, p4]
-        i5 = int_neg(i2)
         p2 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p2, p4, descr=nextdescr)
         setfield_gc(p1, p2, descr=nextdescr)
-        jump(p1, i2, i5, p4)
+        jump(p1, i2, i5, p4, i5)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -5205,7 +5206,6 @@
         """
         expected = """
         [p0]
-        p1 = getfield_gc(p0, descr=valuedescr)
         setfield_gc(p0, p0, descr=valuedescr)
         jump(p0)
         """
@@ -6216,12 +6216,25 @@
         p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
         jump(p25, p187, i184)
         """
-        expected = """
-        [p25, p187, i184]
-        jump(p25, p187, i184)
-        """
-        self.optimize_loop(ops, expected, ops)
-        # FIXME: check jumparg 0 == getfield_gc()
+        preamble = """
+        [p1, p187, i184]
+        p188 = getarrayitem_gc(p187, 42, descr=<GcPtrArrayDescr>)
+        guard_value(p188, ConstPtr(myptr)) []
+        p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
+        jump(p25, p187, i184, p25)
+        """
+        short = """
+        [p1, p187, i184]
+        p188 = getarrayitem_gc(p187, 42, descr=<GcPtrArrayDescr>)
+        guard_value(p188, ConstPtr(myptr)) []
+        p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
+        jump(p1, p187, i184, p25)
+        """
+        expected = """
+        [p25, p187, i184, p189]
+        jump(p189, p187, i184, p189)
+        """
+        self.optimize_loop(ops, expected, preamble, expected_short=short)
 
     def test_constant_getfield1bis(self):
         ops = """
@@ -6305,9 +6318,11 @@
         self.optimize_loop(ops, expected)
 
     def test_dont_cache_setfields(self):
-        # Caching the last two getfields here would specialize the loop to the 
state where
-        # the first two getfields return the same value. This state needs to 
be guarded for
-        # in the short preamble.
+        # Naivly caching the last two getfields here would specialize
+        # the loop to the state where the first two getfields return
+        # the same value. That state would need to be guarded for
+        # in the short preamble. Instead we make sure to keep the
+        # results of the two getfields as separate boxes.
         ops = """
         [p0, p1, ii, ii2]
         i1 = getfield_gc(p0, descr=valuedescr)
@@ -6319,14 +6334,21 @@
         i5 = getfield_gc(p1, descr=otherdescr)
         jump(p0, p1, ii2, ii)
         """
-        expected = """
+        preamble = """
         [p0, p1, ii, ii2]
         i1 = getfield_gc(p0, descr=valuedescr)
         i2 = getfield_gc(p1, descr=otherdescr)
         i3 = int_add(i1, i2)
         setfield_gc(p0, ii, descr=valuedescr)
         setfield_gc(p1, ii, descr=otherdescr)
-        jump(p0, p1, ii2, ii)
+        jump(p0, p1, ii2, ii, ii, ii)
+        """
+        expected = """
+        [p0, p1, ii, ii2, i1, i2]
+        i3 = int_add(i1, i2)
+        setfield_gc(p0, ii, descr=valuedescr)
+        setfield_gc(p1, ii, descr=otherdescr)
+        jump(p0, p1, ii2, ii, ii, ii)
         """
         self.optimize_loop(ops, expected)
 
@@ -6743,6 +6765,22 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_keep_getfields_and_inputargs_separate(self):
+        ops = """
+        [p0]
+        call(p0, descr=nonwritedescr)
+        p1 = getfield_gc(ConstPtr(myptr), descr=nextdescr)
+        call(p1, descr=writeadescr)
+        jump(p1)
+        """
+        expected = """
+        [p0, p1]
+        call(p0, descr=nonwritedescr)
+        call(p1, descr=writeadescr)
+        jump(p1, p1)
+        """
+        self.optimize_loop(ops, expected)        
+
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
         
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
@@ -209,7 +209,7 @@
                 debug_print('inputargs:       ' + args)
                 args = ", ".join([logops.repr_of_arg(arg) for arg in 
short_inputargs])
                 debug_print('short inputargs: ' + args)
-                self.short_boxes.debug_print(logops)
+                self.short_boxes.debug_print(logops)            
 
             # Force virtuals amoung the jump_args of the preamble to get the
             # operations needed to setup the proper state of those virtuals
@@ -249,7 +249,7 @@
                     newresult = 
self.optimizer.getvalue(op.result).get_key_box()
                     if newresult is not op.result:
                         self.short_boxes.alias(newresult, op.result)
-                    
+
             self.optimizer.flush()
             self.optimizer.emitting_dissabled = False
 
@@ -268,7 +268,8 @@
             #    preamble_optimizer.send_extra_operation(jumpop)
             #    return
             loop.inputargs = inputargs
-            args = [self.short_boxes.original(a) for a in inputargs]
+            args = 
[preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box()\
+                    for a in inputargs]
             jmp = ResOperation(rop.JUMP, args, None)
             jmp.setdescr(loop.token)
             loop.preamble.operations.append(jmp)
@@ -376,29 +377,29 @@
                     
 
         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()
-
-            if self.optimizer.loop.logops:
-                debug_print('OP: ' + 
self.optimizer.loop.logops.repr_of_resop(op))
-            for a in args:
-                if self.optimizer.loop.logops:
-                    debug_print('A:  ' + 
self.optimizer.loop.logops.repr_of_arg(a))
-                self.import_box(a, inputargs, short, short_jumpargs,
-                                jumpargs, short_seen)
-            i += 1
-
+        while i < len(self.optimizer.newoperations) or j < len(jumpargs):
             if i == len(self.optimizer.newoperations):
                 while j < len(jumpargs):
                     a = jumpargs[j]
                     self.import_box(a, inputargs, short, short_jumpargs,
                                     jumpargs, short_seen)
                     j += 1
+            else:
+                op = self.optimizer.newoperations[i]
+
+                self.boxes_created_this_iteration[op.result] = True
+                args = op.getarglist()
+                if op.is_guard():
+                    args = args + op.getfailargs()
+
+                if self.optimizer.loop.logops:
+                    debug_print('OP: ' + 
self.optimizer.loop.logops.repr_of_resop(op))
+                for a in args:
+                    if self.optimizer.loop.logops:
+                        debug_print('A:  ' + 
self.optimizer.loop.logops.repr_of_arg(a))
+                    self.import_box(a, inputargs, short, short_jumpargs,
+                                    jumpargs, short_seen)
+                i += 1
 
         jumpop.initarglist(jumpargs)
         self.optimizer.send_extra_operation(jumpop)
@@ -445,6 +446,7 @@
                 return self.short_inliner.inline_arg(op.result)
             else:
                 return None
+        
         for a in op.getarglist():
             if not isinstance(a, Const) and a not in short_seen:
                 self.add_op_to_short(self.short_boxes.producer(a), short, 
short_seen,
@@ -479,7 +481,6 @@
         
     def import_box(self, box, inputargs, short, short_jumpargs,
                    jumpargs, short_seen):
-
         if isinstance(box, Const) or box in inputargs:
             return
         if box in self.boxes_created_this_iteration:
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py 
b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -456,12 +456,14 @@
 class ShortBoxes(object):
     def __init__(self, optimizer, surviving_boxes):
         self.potential_ops = {}
+        self.duplicates = {}
+        self.optimizer = optimizer
+        for box in surviving_boxes:
+            self.potential_ops[box] = None
         optimizer.produce_potential_short_preamble_ops(self)
 
         self.aliases = {}
         self.short_boxes = {}
-        for box in surviving_boxes:
-            self.short_boxes[box] = None
 
         for box in self.potential_ops.keys():
             try:
@@ -476,14 +478,30 @@
             return 
         if box in self.potential_ops:
             op = self.potential_ops[box]
-            for arg in op.getarglist():
-                self.produce_short_preamble_box(arg)
+            if op:
+                for arg in op.getarglist():
+                    self.produce_short_preamble_box(arg)
             self.short_boxes[box] = op
         else:
             raise BoxNotProducable
 
     def add_potential(self, op):
-        self.potential_ops[op.result] = op
+        if op.result not in self.potential_ops:
+            self.potential_ops[op.result] = op
+            return op
+        newop = op.clone()
+        newop.result = op.result.clonebox()
+        self.potential_ops[newop.result] = newop
+        if op.result in self.duplicates:
+            self.duplicates[op.result].append(newop.result)
+        else:
+            self.duplicates[op.result] = [newop.result]
+        self.optimizer.send_extra_operation(newop)
+        if newop.is_ovf():
+            guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
+            self.optimizer.send_extra_operation(guard)
+        return newop
+        
 
     def debug_print(self, logops):
         debug_start('jit-short-boxes')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to