[pypy-svn] r68136 - in pypy/trunk/pypy/jit/metainterp: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Oct 3 12:02:18 CEST 2009


Author: cfbolz
Date: Sat Oct  3 12:02:17 2009
New Revision: 68136

Modified:
   pypy/trunk/pypy/jit/metainterp/history.py
   pypy/trunk/pypy/jit/metainterp/optimizeopt.py
   pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
(pedronis, cfbolz): do common expression elimination of pure ops. This will be
reverted, it's a bit lost in the noise. Checking it in to not lose it.


Modified: pypy/trunk/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/history.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/history.py	Sat Oct  3 12:02:17 2009
@@ -246,6 +246,7 @@
         return repr_rpython(self, 'ci')
 constint_lower = -5
 constint_upper = 200
+assert rop._LAST < constint_upper
 ConstInt.PREBUILT = [ConstInt(i) for i in range(constint_lower, constint_upper)]
 
 def constint(x):

Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py	Sat Oct  3 12:02:17 2009
@@ -12,7 +12,7 @@
 from pypy.jit.metainterp.optimizeutil import InvalidLoop
 from pypy.jit.metainterp import resume, compile
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, r_dict
 from pypy.rpython.lltypesystem import lltype
 
 def optimize_loop_1(cpu, loop):
@@ -348,6 +348,23 @@
             subspecnode.teardown_virtual_node(optimizer, subvalue, newexitargs)
 
 
+def hash_op(op):
+    from pypy.rlib.rarithmetic import intmask
+    mult = 1000003
+    x = 0x345678 ^ op.opnum
+    z = len(op.args)
+    for box in op.args:
+        y = hash(box)
+        x = (x ^ y) * mult
+        z -= 1
+        mult += 82520 + z + z
+    x += 97531
+    return intmask(x)
+
+def eq_op(op1, op2):
+    return op1.opnum == op2.opnum and op1.args == op2.args
+
+
 class Optimizer(object):
 
     def __init__(self, cpu, loop):
@@ -362,6 +379,7 @@
         self.values_to_clean = {}
                                      
         self.interned_refs = {}
+        self.emitted_pure_ops = r_dict(eq_op, hash_op)
 
     def getinterned(self, box):
         constbox = self.get_constant_box(box)
@@ -378,7 +396,7 @@
                 self.interned_refs[key] = box
                 return box
         else:
-            return box
+            return constbox
 
     def getvalue(self, box):
         box = self.getinterned(box)
@@ -494,7 +512,14 @@
                         op = op.clone()
                         must_clone = False
                     op.args[i] = box
-        if op.is_guard():
+        if op.is_always_pure():
+            oldresult = self.emitted_pure_ops.get(op, None)
+            if oldresult:
+                self.make_equal_to(op.result, self.getvalue(oldresult))
+                return
+            else:
+                self.emitted_pure_ops[op] = op.result
+        elif op.is_guard():
             self.store_final_boxes_in_guard(op)
         elif op.can_raise():
             self.exception_might_have_happened = True
@@ -534,6 +559,7 @@
                 resbox = execute_nonspec(self.cpu, op.opnum, argboxes, op.descr)
                 self.make_constant(op.result, resbox.constbox())
                 return
+
         elif not op.has_no_side_effect() and not op.is_ovf():
             self.clean_fields_of_values()
         # otherwise, the operation remains

Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	Sat Oct  3 12:02:17 2009
@@ -47,6 +47,7 @@
     assert fdescr.rd_virtuals is None
     assert fdescr.rd_consts == []
     assert fdescr.rd_frame_infos == fi
+
 # ____________________________________________________________
 
 def equaloplists(oplist1, oplist2, strict_fail_args=True, remap={}):
@@ -132,6 +133,17 @@
 
 class BaseTestOptimizeOpt(BaseTest):
 
+    def test_getinterned(self):
+        opt = optimizeopt.Optimizer(self.cpu, None)
+        b1 = BoxInt()
+        assert opt.getinterned(b1) is b1
+        opt.make_constant(b1, ConstInt(1))
+        c1 = opt.getinterned(b1)
+        assert isinstance(c1, ConstInt)
+        c1 = self.cpu.ts.ConstRef(self.myptr)
+        c2 = self.cpu.ts.ConstRef(self.myptr)
+        assert opt.getinterned(c1) is opt.getinterned(c2)
+
     def invent_fail_descr(self, fail_args):
         if fail_args is None:
             return None
@@ -409,6 +421,72 @@
         """
         self.optimize_loop(ops, '', expected)
 
+    def test_common_expression_elimination(self):
+        ops = """
+        [i0, i1, i2, i3]
+        ir1 = int_add(i0, 1)
+        ir2 = int_add(i0, 1)
+        ir3 = int_add(i1, i2)
+        ir4 = int_add(i1, i2)
+        jump(ir1, ir2, ir3, ir4)
+        """
+        expected = """
+        [i0, i1, i2, i3]
+        ir1 = int_add(i0, 1)
+        ir3 = int_add(i1, i2)
+        jump(ir1, ir1, ir3, ir3)
+        """
+        self.optimize_loop(ops, 'Not, Not, Not, Not', expected)
+
+        ops = """
+        [p0, p1]
+        pr1 = getfield_gc_pure(p0, descr=valuedescr)
+        pr2 = getfield_gc_pure(p0, descr=valuedescr)
+        jump(pr1, pr2)
+        """
+        expected = """
+        [p0, p1]
+        pr1 = getfield_gc_pure(p0, descr=valuedescr)
+        jump(pr1, pr1)
+        """
+        self.optimize_loop(ops, 'Not, Not', expected)
+
+        ops = """
+        [p0, p1]
+        i1 = oois(p0, p1)
+        guard_value(i1, 1) []
+        i2 = oois(p0, p1)
+        guard_value(i2, 1) []
+        jump(p0, p1)
+        """
+        expected = """
+        [p0, p1]
+        i1 = oois(p0, p1)
+        guard_value(i1, 1) []
+        jump(p0, p1)
+        """
+        self.optimize_loop(ops, 'Not, Not', expected)
+
+    def test_common_expression_elimination_virtual(self):
+        ops = """
+        [p0, p1]
+        i1 = oois(p0, p1)
+        guard_value(i1, 1) []
+        p2 = new_with_vtable(ConstClass(node_vtable))
+        setfield_gc(p2, p0, descr=valuedescr)
+        p3 = getfield_gc(p2, descr=valuedescr)
+        i2 = oois(p3, p1)
+        guard_value(i2, 1) []
+        jump(p0, p1)
+        """
+        expected = """
+        [p0, p1]
+        i1 = oois(p0, p1)
+        guard_value(i1, 1) []
+        jump(p0, p1)
+        """
+        self.optimize_loop(ops, 'Not, Not', expected)
+
     def test_ooisnull_oononnull_via_virtual(self):
         ops = """
         [p0]



More information about the Pypy-commit mailing list