[pypy-svn] r70436 - in pypy/branch/jit-trace-hook/pypy/jit/metainterp: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Jan 7 18:44:44 CET 2010


Author: cfbolz
Date: Thu Jan  7 18:44:43 2010
New Revision: 70436

Modified:
   pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py
   pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Add an optimization that removes a pure operation if it has already been seen.


Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py	Thu Jan  7 18:44:43 2010
@@ -11,7 +11,7 @@
 from pypy.jit.metainterp.specnode import VirtualStructSpecNode
 from pypy.jit.metainterp.optimizeutil import _findall, sort_descrs
 from pypy.jit.metainterp.optimizeutil import descrlist_dict
-from pypy.jit.metainterp.optimizeutil import InvalidLoop
+from pypy.jit.metainterp.optimizeutil import InvalidLoop, args_dict
 from pypy.jit.metainterp import resume, compile
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.rlib.objectmodel import we_are_translated
@@ -388,6 +388,7 @@
         self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd)
         self.heap_op_optimizer = HeapOpOptimizer(self)
         self.bool_boxes = {}
+        self.pure_operations = args_dict()
 
     def forget_numberings(self, virtualbox):
         self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS)
@@ -574,6 +575,22 @@
                 resbox = execute_nonspec(self.cpu, op.opnum, argboxes, op.descr)
                 self.make_constant(op.result, resbox.constbox())
                 return
+
+            # did we do the exact same operation already?
+            args = op.args[:]
+            for i in range(len(args)):
+                arg = args[i]
+                if arg in self.values:
+                    args[i] = self.values[arg].get_key_box()
+            args.append(ConstInt(op.opnum))
+            oldop = self.pure_operations.get(args, None)
+            if oldop is not None:
+                assert oldop.opnum == op.opnum
+                self.make_equal_to(op.result, self.getvalue(oldop.result))
+                return
+            else:
+                self.pure_operations[args] = op
+
         # otherwise, the operation remains
         self.emit_operation(op)
 

Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py	(original)
+++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py	Thu Jan  7 18:44:43 2010
@@ -1,7 +1,7 @@
 from pypy.rlib.objectmodel import r_dict, compute_identity_hash
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.jit.metainterp import resoperation
+from pypy.jit.metainterp import resoperation, history
 
 class InvalidLoop(Exception):
     """Raised when the optimize*.py detect that the loop that
@@ -59,3 +59,35 @@
 def descrlist_dict():
     return r_dict(descrlist_eq, descrlist_hash)
 
+# ____________________________________________________________
+
+def args_eq(args1, args2):
+    if len(args1) != len(args2):
+        return False
+    for i in range(len(args1)):
+        arg1 = args1[i]
+        arg2 = args2[i]
+        if isinstance(arg1, history.Const):
+            if arg1.__class__ is not arg2.__class__:
+                return False
+            if not arg1.same_constant(arg2):
+                return False
+        else:
+            if not arg1 is arg2:
+                return False
+    return True
+
+def args_hash(args):
+    res = 0x345678
+    for arg in args:
+        if isinstance(arg, history.Const):
+            y = arg._get_hash_()
+        else:
+            y = compute_identity_hash(arg)
+        res = intmask((1000003 * res) ^ y)
+    return res
+
+def args_dict():
+    return r_dict(args_eq, args_hash)
+
+

Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py	Thu Jan  7 18:44:43 2010
@@ -1834,6 +1834,30 @@
         """
         self.optimize_loop(ops, "Not", expected)
 
+    def test_remove_duplicate_pure_op(self):
+        ops = """
+        [p1, p2]
+        i1 = oois(p1, p2)
+        i2 = oois(p1, p2)
+        i3 = int_add(i1, 1)
+        i4 = int_add(i2, 1)
+        escape(i3)
+        escape(i4)
+        guard_true(i1) []
+        guard_true(i2) []
+        jump(p1, p2)
+        """
+        expected = """
+        [p1, p2]
+        i1 = oois(p1, p2)
+        i3 = int_add(i1, 1)
+        escape(i3)
+        escape(i3)
+        guard_true(i1) []
+        jump(p1, p2)
+        """
+        self.optimize_loop(ops, "Not, Not", expected)
+
     # ----------
 
     def make_fail_descr(self):



More information about the Pypy-commit mailing list