[pypy-svn] r66415 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Sun Jul 19 18:57:10 CEST 2009


Author: arigo
Date: Sun Jul 19 18:57:09 2009
New Revision: 66415

Modified:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Basic constant propagation.


Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	Sun Jul 19 18:57:09 2009
@@ -1,3 +1,85 @@
+from pypy.jit.metainterp.history import Const, Box
+from pypy.jit.metainterp.optimizeutil import av_newdict, _findall
+from pypy.rlib.objectmodel import we_are_translated
+
 
 def optimize(loop):
-    pass
+    """Optimize loop.operations to make it match the input of loop.specnodes
+    and to remove internal overheadish operations.  Note that loop.specnodes
+    must be applicable to the loop; you will probably get an AssertionError
+    if not.
+    """
+    Optimizer().optimize(loop)
+
+# ____________________________________________________________
+
+
+class Optimizer(object):
+
+    def __init__(self):
+        # set of Boxes; the value is not stored in the dict, but can
+        # be accessed as the Box.getint() or get_().
+        self._consts = {}
+
+    def is_constant(self, box):
+        return isinstance(box, Const) or box in self._consts
+
+    def make_constant(self, box):
+        assert isinstance(box, Box)
+        self._consts[box] = box.constbox()
+
+    def rename_argument(self, box):
+        return self._consts.get(box, box)
+
+    # ----------
+
+    def optimize(self, loop):
+        self.newoperations = []
+        for op in loop.operations:
+            opnum = op.opnum
+            for value, func in optimize_ops:
+                if opnum == value:
+                    func(self, op)
+                    break
+            else:
+                self.optimize_default(op)
+        loop.operations = self.newoperations
+
+    def emit_operation(self, op):
+        op2 = op.clone()
+        op2.args = [self.rename_argument(box) for box in op.args]
+        self.newoperations.append(op2)
+
+    def optimize_default(self, op):
+        if op.is_always_pure():
+            for box in op.args:
+                if not self.is_constant(box):
+                    break
+            else:
+                # all constant arguments: constant-fold away
+                self.make_constant(op.result)
+                return
+        # otherwise, the operation remains
+        self.emit_operation(op)
+
+    def optimize_GUARD_VALUE(self, op):
+        if self.is_constant(op.args[0]):
+            assert isinstance(op.args[1], Const)
+            assert self.rename_argument(op.args[0]).get_() == op.args[1].get_()
+        else:
+            self.emit_operation(op)
+
+    def optimize_GUARD_TRUE(self, op):
+        if self.is_constant(op.args[0]):
+            assert self.rename_argument(op.args[0]).getint()
+        else:
+            self.emit_operation(op)
+
+    def optimize_GUARD_FALSE(self, op):
+        if self.is_constant(op.args[0]):
+            assert not self.rename_argument(op.args[0]).getint()
+        else:
+            self.emit_operation(op)
+
+
+optimize_ops = _findall(Optimizer, 'optimize_')

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py	Sun Jul 19 18:57:09 2009
@@ -22,7 +22,7 @@
 class VirtualInstanceSpecNode(SpecNode):
     def __init__(self, known_class, fields):
         self.known_class = known_class
-        self.fields = fields
+        self.fields = fields    # list: [(fieldofs, subspecnode)]
 
     def _equals(self, other):   # for tests only
         ok = (type(other) is VirtualInstanceSpecNode and

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	Sun Jul 19 18:57:09 2009
@@ -53,8 +53,9 @@
         assert equaloplists(optimized.operations,
                             expected.operations)
 
-    def optimize(self, ops, spectext, optops, boxkinds=None):
+    def optimize(self, ops, spectext, optops, boxkinds=None, **values):
         loop = self.parse(ops, boxkinds=boxkinds)
+        loop.setvalues(**values)
         loop.specnodes = self.unpack_specnodes(spectext)
         optimize(loop)
         expected = self.parse(optops, boxkinds=boxkinds)
@@ -70,6 +71,26 @@
         """
         self.optimize(ops, 'Not', ops)
 
+    def test_constant_propagate(self):
+        ops = """
+        []
+        i0 = int_add(2, 3)
+        i1 = int_is_true(i0)
+        guard_true(i1)
+          fail()
+        i2 = bool_not(i1)
+        guard_false(i2)
+          fail()
+        guard_value(i0, 5)
+          fail()
+        jump()
+        """
+        expected = """
+        []
+        jump()
+        """
+        self.optimize(ops, '', expected, i0=5, i1=1, i2=0)
+
 
 class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin):
     pass



More information about the Pypy-commit mailing list