[pypy-svn] r65363 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test

antocuni at codespeak.net antocuni at codespeak.net
Sat May 23 17:49:30 CEST 2009


Author: antocuni
Date: Sat May 23 17:49:29 2009
New Revision: 65363

Added:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
      - copied, changed from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
      - copied, changed from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
yet another optimize*.py.  The idea is that you can write a new class for each
optimization, and methods of the class will be called for each corresponding
operation.



Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py	Sat May 23 17:49:29 2009
@@ -1,6 +1,3 @@
-
-""" Simplified optimize.py
-"""
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.history import Const, Box
 
@@ -27,6 +24,9 @@
     loop = None
     nodes = None
 
+    def __init__(self, optlist):
+        self.optlist = optlist
+
     def getnode(self, box):
         try:
             return self.nodes[box]
@@ -75,74 +75,16 @@
             newboxes.append(box)
         return newboxes
 
-    def optimize_guard(self, op):
-        assert len(op.suboperations) == 1
-        op_fail = op.suboperations[0]
-        op_fail.args = self.new_arguments(op_fail)
-        # modification in place. Reason for this is explained in mirror
-        # in optimize.py
-        op.suboperations = [op_fail]
-
     def optimize_operations(self):
         newoperations = []
         for op in self.loop.operations:
-            if op.is_guard():
-                if op.opnum == rop.GUARD_NONVIRTUALIZED:
-                    continue
-                elif op.opnum == rop.GUARD_CLASS:
-                    node = self.getnode(op.args[0])
-                    if node.cls is not None:
-                        # assert that they're equal maybe
-                        continue
-                    node.cls = InstanceNode(op.args[1], const=True)
-                elif op.opnum == rop.GUARD_VALUE:
-                    instnode = self.nodes[op.args[0]]
-                    assert isinstance(op.args[1], Const)
-                    if instnode.const:
-                        continue
-                    self.optimize_guard(op)
-                    instnode.const = True
-                    instnode.source = op.args[0].constbox()
-                    newoperations.append(op)
-                    continue
-                self.optimize_guard(op)
-                newoperations.append(op)
-                continue
-            elif op.opnum == rop.GETFIELD_GC:
-                instnode = self.getnode(op.args[0])
-                descr = op.descr
-                node = instnode.cleanfields.get(descr, None)
-                if node is not None:
-                    self.nodes[op.result] = node
-                    continue
-                else:
-                    instnode.cleanfields[descr] = self.getnode(op.result)
-            elif op.opnum == rop.SETFIELD_GC:
-                instnode = self.getnode(op.args[0])
-                descr = op.descr
-                node = self.getnode(op.args[1])
-                instnode.dirtyfields[descr] = node
-                instnode.cleanfields[descr] = node
-                l = self.field_caches.setdefault(descr, [])
-                l.append((instnode, node))
-                continue
-            # default handler
-            op = op.clone()
-            op.args = self.new_arguments(op)
-            if op.is_always_pure():
-                for box in op.args:
-                    if isinstance(box, Box):
-                        break
-                else:
-                    # all constant arguments: constant-fold away
-                    box = op.result
-                    assert box is not None
-                    instnode = InstanceNode(box.constbox(), const=True)
-                    self.nodes[box] = instnode
-                    continue
-            elif not op.has_no_side_effect():
-                self.clean_up_caches(newoperations)
-            newoperations.append(op)
+            newop = op
+            for optimization in self.optlist:
+                newop = optimization.handle_op(self, newop)
+                if newop is None:
+                    break
+            if newop is not None:
+                newoperations.append(newop)
         print "Length of the loop:", len(newoperations)
         self.loop.operations = newoperations
 
@@ -161,7 +103,77 @@
         self.find_nodes()
         self.optimize_operations()
 
-specializer = Specializer()
+# -------------------------------------------------------------------
+
+class AbstractOptimization(object):
+
+    def __init__(self):
+        'NOT_RPYTHON'
+        operations = [None] * (rop._LAST+1)
+        for key, value in rop.__dict__.items():
+            if key.startswith('_'):
+                continue
+            methname = key.lower()
+            if hasattr(self, methname):
+                func = getattr(self, methname).im_func
+            else:
+                func = getattr(self, 'handle_default_op').im_func
+            operations[value] = func
+        self.operations = operations
+
+    def handle_op(self, spec, op):
+        func = self.operations[op.opnum]
+        return func(self, spec, op)
+    
+    def handle_default_op(self, spec, op):
+        return op
+
+
+class OptimizeGuards(AbstractOptimization):
+
+    def optimize_guard(self, spec, op):
+        assert len(op.suboperations) == 1
+        op_fail = op.suboperations[0]
+        op_fail.args = spec.new_arguments(op_fail)
+        # modification in place. Reason for this is explained in mirror
+        # in optimize.py
+        op.suboperations = [op_fail]
+        return op
+
+    def guard_class(self, spec, op):
+        node = spec.getnode(op.args[0])
+        if node.cls is not None:
+            # assert that they're equal maybe
+            return
+        node.cls = InstanceNode(op.args[1], const=True)
+        return self.optimize_guard(spec, op)
+
+##     def guard_value(self, spec, op):
+##         instnode = spec.nodes[op.args[0]]
+##         assert isinstance(op.args[1], Const)
+##         if instnode.const:
+##             return
+##         self.optimize_guard(spec, op)
+##         instnode.const = True
+##         instnode.source = op.args[0].constbox()
+##         return op
+
+##     def guard_nonvirtualized(self, spec, op):
+##         return
+
+##     def handle_default_op(self, spec, op):
+##         if op.is_guard():
+##             return self.optimize_guard(op)
+##         return op
+
+
+
+# -------------------------------------------------------------------
+
+OPTLIST = [
+    OptimizeGuards(),
+    ]
+specializer = Specializer(OPTLIST)
 
 def optimize_loop(options, old_loops, loop, cpu=None):
     if old_loops:

Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py	Sat May 23 17:49:29 2009
@@ -8,9 +8,31 @@
      ConstInt, BoxInt, BoxObj, ConstObj
 from pypy.jit.backend.llgraph import runner
 
-from pypy.jit.metainterp.optimize2 import optimize_loop
+from pypy.jit.metainterp.optimize3 import AbstractOptimization
+from pypy.jit.metainterp.optimize3 import optimize_loop
 from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
 
+def test_AbstractOptimization():
+    
+    class MyOpt(AbstractOptimization):
+        def int_add(self, spec, op):
+            return 'hello world', op
+
+    class MyOpt2(MyOpt):
+        def handle_default_op(self, spec, op):
+            return 'default op', op
+
+    myopt = MyOpt()
+    myopt2 = MyOpt2()
+    op = ResOperation(rop.INT_ADD, [], None)
+    assert myopt.handle_op(None, op) == ('hello world', op)
+    assert myopt2.handle_op(None, op) == ('hello world', op)
+
+    op = ResOperation(rop.INT_SUB, [], None)
+    assert myopt.handle_op(None, op) == op
+    assert myopt2.handle_op(None, op) == ('default op', op)
+
+
 class LLtypeMixin(object):
 
     node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -42,7 +64,7 @@
 
 
 
-class BaseTestOptimize2(object):
+class BaseTestOptimize3(object):
 
     @staticmethod
     def newloop(inputargs, operations):
@@ -51,6 +73,7 @@
         loop.operations = operations
         return loop
 
+
     def test_remove_guard_class(self):
         ops = [
             ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
@@ -63,6 +86,7 @@
         assert len(loop.operations) == 1
 
     def test_remove_consecutive_guard_value_constfold(self):
+        py.test.skip('in-progress')
         n = BoxInt(0)
         n1 = BoxInt(1)
         n2 = BoxInt(3)
@@ -81,6 +105,7 @@
             ])
 
     def test_remove_consecutive_getfields(self):
+        py.test.skip('in-progress')
         n1 = BoxInt()
         n2 = BoxInt()
         n3 = BoxInt()
@@ -97,6 +122,7 @@
             ])
 
     def test_setfield_getfield_clean_cache(self):
+        py.test.skip('in-progress')
         n1 = BoxInt()
         n2 = BoxInt()
         n3 = BoxInt()
@@ -115,8 +141,8 @@
             ])
 
 
-class TestLLtype(LLtypeMixin, BaseTestOptimize2):
+class TestLLtype(LLtypeMixin, BaseTestOptimize3):
     pass
 
-class TestOOtype(OOtypeMixin, BaseTestOptimize2):
+class TestOOtype(OOtypeMixin, BaseTestOptimize3):
     pass



More information about the Pypy-commit mailing list