[pypy-svn] r77545 - in pypy/branch/jit-unroll-loops/pypy/jit/metainterp: optimizeopt test

hakanardo at codespeak.net hakanardo at codespeak.net
Sat Oct 2 10:31:31 CEST 2010


Author: hakanardo
Date: Sat Oct  2 10:31:29 2010
New Revision: 77545

Modified:
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py
Log:
Look ahead on future operations using optimizer.operations no longer suported. test_loop_invariant_mul_ovf passing.

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py	Sat Oct  2 10:31:29 2010
@@ -9,14 +9,28 @@
     """Keeps track of the bounds placed on integers by the guards and
        remove redundant guards"""
 
+    def setup(self, virtuals):
+        self.posponedop = None
+        self.nextop = None
+
     def propagate_forward(self, op):
+        if op.is_ovf():
+            self.posponedop = op
+            return
+        if self.posponedop:
+            self.nextop = op
+            op = self.posponedop
+            self.posponedop = None
+            
         opnum = op.getopnum()
         for value, func in optimize_ops:
             if opnum == value:
                 func(self, op)
                 break
         else:
+            assert not op.is_ovf()
             self.emit_operation(op)
+            
 
     def propagate_bounds_backward(self, box):
         # FIXME: This takes care of the instruction where box is the reuslt
@@ -85,45 +99,45 @@
         v2 = self.getvalue(op.getarg(1))
         resbound = v1.intbound.add_bound(v2.intbound)
         if resbound.has_lower and resbound.has_upper and \
-           self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+           self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
             # Transform into INT_ADD and remove guard
             op = op.copy_and_change(rop.INT_ADD)
-            self.skip_nextop()
             self.optimize_INT_ADD(op) # emit the op
         else:
             self.emit_operation(op)
             r = self.getvalue(op.result)
             r.intbound.intersect(resbound)
+            self.emit_operation(self.nextop)
 
     def optimize_INT_SUB_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         resbound = v1.intbound.sub_bound(v2.intbound)
         if resbound.has_lower and resbound.has_upper and \
-               self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+               self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
             # Transform into INT_SUB and remove guard
             op = op.copy_and_change(rop.INT_SUB)
-            self.skip_nextop()
             self.optimize_INT_SUB(op) # emit the op
         else:
             self.emit_operation(op)
             r = self.getvalue(op.result)
             r.intbound.intersect(resbound)
-
+            self.emit_operation(self.nextop)
+            
     def optimize_INT_MUL_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         resbound = v1.intbound.mul_bound(v2.intbound)
         if resbound.has_lower and resbound.has_upper and \
-               self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+               self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
             # Transform into INT_MUL and remove guard
             op = op.copy_and_change(rop.INT_MUL)
-            self.skip_nextop()
             self.optimize_INT_MUL(op) # emit the op
         else:
             self.emit_operation(op)
             r = self.getvalue(op.result)
             r.intbound.intersect(resbound)
+            self.emit_operation(self.nextop)
 
     def optimize_INT_LT(self, op):
         v1 = self.getvalue(op.getarg(0))

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py	Sat Oct  2 10:31:29 2010
@@ -182,12 +182,6 @@
         op = ResOperation(opnum, args, result)
         self.optimizer.pure_operations[self.optimizer.make_args_key(op)] = op
 
-    def nextop(self):
-        return self.optimizer.loop.operations[self.optimizer.i + 1]
-
-    def skip_nextop(self):
-        self.optimizer.i += 1
-
     def setup(self, virtuals):
         pass
 
@@ -205,6 +199,7 @@
         self.pure_operations = args_dict()
         self.producer = {}
         self.pendingfields = []
+        self.posponedop = None
 
         if optimizations:
             self.first_optimization = optimizations[0]
@@ -254,9 +249,9 @@
             return constbox
         return None
 
-    def make_equal_to(self, box, value):
+    def make_equal_to(self, box, value, replace=False):
         assert isinstance(value, OptValue)
-        assert box not in self.values
+        assert replace or box not in self.values
         self.values[box] = value
 
     def make_constant(self, box, constbox):
@@ -392,10 +387,17 @@
 
     def optimize_default(self, op):
         canfold = op.is_always_pure()
-        is_ovf = op.is_ovf()
-        if is_ovf:
-            nextop = self.loop.operations[self.i + 1]
+        if op.is_ovf():
+            self.posponedop = op
+            return
+        if self.posponedop:
+            nextop = op
+            op = self.posponedop
+            self.posponedop = None
             canfold = nextop.getopnum() == rop.GUARD_NO_OVERFLOW
+        else:
+            nextop = None
+            
         if canfold:
             for i in range(op.numargs()):
                 if self.get_constant_box(op.getarg(i)) is None:
@@ -406,9 +408,8 @@
                             for i in range(op.numargs())]
                 resbox = execute_nonspec(self.cpu, None,
                                          op.getopnum(), argboxes, op.getdescr())
+                # FIXME: Don't we need to check for an overflow here?
                 self.make_constant(op.result, resbox.constbox())
-                if is_ovf:
-                    self.i += 1 # skip next operation, it is the unneeded guard
                 return
 
             # did we do the exact same operation already?
@@ -416,20 +417,22 @@
             oldop = self.pure_operations.get(args, None)
             if oldop is not None and oldop.getdescr() is op.getdescr():
                 assert oldop.getopnum() == op.getopnum()
-                self.make_equal_to(op.result, self.getvalue(oldop.result))
-                if is_ovf:
-                    self.i += 1 # skip next operation, it is the unneeded guard
+                self.make_equal_to(op.result, self.getvalue(oldop.result),
+                                   True)
                 return
             else:
                 self.pure_operations[args] = op
 
         # otherwise, the operation remains
         self.emit_operation(op)
+        if nextop:
+            self.emit_operation(nextop)
 
-    def optimize_GUARD_NO_OVERFLOW(self, op):
-        # otherwise the default optimizer will clear fields, which is unwanted
-        # in this case
-        self.emit_operation(op)
+    #def optimize_GUARD_NO_OVERFLOW(self, op):
+    #    # otherwise the default optimizer will clear fields, which is unwanted
+    #    # in this case
+    #    self.emit_operation(op)
+    # FIXME: Is this still needed?
 
     def optimize_DEBUG_MERGE_POINT(self, op):
         self.emit_operation(op)

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py	Sat Oct  2 10:31:29 2010
@@ -334,11 +334,11 @@
             return res
         res = self.meta_interp(f, [6, 7])
         assert res == 308
-        self.check_loop_count(1)
-        self.check_loops({'guard_true': 1, 'guard_no_overflow': 1,
-                          'int_add': 2, 'int_sub': 1, 'int_gt': 1,
-                          'int_mul': 1, 'int_mul_ovf': 1,
-                          'jump': 1})
+        self.check_loop_count(2)
+        self.check_loops({'guard_true': 2, 'guard_no_overflow': 1,
+                          'int_add': 4, 'int_sub': 2, 'int_gt': 2,
+                          'int_mul': 2, 'int_mul_ovf': 1,
+                          'jump': 2})
 
     def test_loop_invariant_mul_bridge1(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -364,12 +364,12 @@
                 myjitdriver.can_enter_jit(x=x, y=y, res=res)
                 myjitdriver.jit_merge_point(x=x, y=y, res=res)
                 res += x * x
-                if y<8:
+                if y<16:
                     res += 1
                 y -= 1
             return res
-        res = self.meta_interp(f, [6, 16])
-        assert res == 583
+        res = self.meta_interp(f, [6, 32])
+        assert res == 1167
         self.check_loop_count(3)
         self.check_loops({'int_lt': 1, 'int_gt': 1,
                           'guard_false': 1, 'guard_true': 1,



More information about the Pypy-commit mailing list