[pypy-svn] r73940 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 21 16:12:22 CEST 2010


Author: arigo
Date: Wed Apr 21 16:12:21 2010
New Revision: 73940

Added:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py   (contents, props changed)
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py   (contents, props changed)
Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
Log:
Add jitter.py, for now only to put the optimizer for 'goto_if_not_xxx' in it.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py	Wed Apr 21 16:12:21 2010
@@ -2,6 +2,7 @@
 from pypy.jit.codewriter.regalloc import perform_register_allocation
 from pypy.jit.codewriter.flatten import flatten_graph, KINDS
 from pypy.jit.codewriter.assembler import Assembler
+from pypy.jit.codewriter.jitter import transform_graph
 
 
 class CodeWriter(object):
@@ -16,6 +17,7 @@
         return self.transform_graph_to_jitcode(graph)
 
     def transform_graph_to_jitcode(self, graph):
+        transform_graph(graph)
         regallocs = {}
         for kind in KINDS:
             regallocs[kind] = perform_register_allocation(graph, kind)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	Wed Apr 21 16:12:21 2010
@@ -1,5 +1,6 @@
 from pypy.objspace.flow.model import Variable
 from pypy.jit.metainterp.history import getkind
+from pypy.rpython.lltypesystem import lltype
 
 
 class SSARepr(object):
@@ -112,39 +113,27 @@
             assert link.exitcase is None
             self.make_link(link)
         else:
-            assert len(block.exits) == 2
+            assert len(block.exits) == 2, "XXX"
             linkfalse, linktrue = block.exits
             if linkfalse.llexitcase == True:
                 linkfalse, linktrue = linktrue, linkfalse
+            if isinstance(block.exitswitch, tuple):
+                # special case produced by jitter.optimize_goto_if_not()
+                opname = 'goto_if_not_' + block.exitswitch[0]
+                opargs = block.exitswitch[1:]
+            else:
+                assert block.exitswitch.concretetype == lltype.Bool
+                opname = 'goto_if_not'
+                opargs = [block.exitswitch]
             #
-            self.emitline('goto_if_not', TLabel(linkfalse),
-                          self.getcolor(block.exitswitch))
+            self.emitline(opname, TLabel(linkfalse),
+                          *self.flatten_list(opargs))
             # true path:
             self.make_link(linktrue)
             # false path:
             self.emitline(Label(linkfalse))
             self.make_link(linkfalse)
 
-    def optimize_goto_if_not(self, block):
-        xxxxxxx
-        if not self.optimize:
-            raise CannotOptimize
-        v = block.exitswitch
-        for link in block.exits:
-            if v in link.args:
-                raise CannotOptimize   # variable escapes to next block
-        for op in block.operations[::-1]:
-            if v in op.args:
-                raise CannotOptimize   # variable is also used in cur block
-            if v is op.result:
-                if op.opname not in ('int_lt', 'int_le', 'int_eq', 'int_ne',
-                                     'int_gt', 'int_ge'):
-                    raise CannotOptimize    # not a supported operation
-                killop = (op.opname,) + tuple(op.args) + (v,)
-                self.assembler.insns.remove(killop)
-                return 'goto_if_not_' + op.opname, op.args
-        raise CannotOptimize   # variable is not produced in cur block
-
     def insert_renamings(self, link):
         renamings = {}
         lst = [(v, self.getcolor(link.target.inputargs[i]))
@@ -173,12 +162,16 @@
     def emitline(self, *line):
         self.assembler.insns.append(line)
 
-    def serialize_op(self, op):
+    def flatten_list(self, list):
         args = []
-        for v in op.args:
+        for v in list:
             if isinstance(v, Variable):
                 v = self.getcolor(v)
             args.append(v)
+        return args
+
+    def serialize_op(self, op):
+        args = self.flatten_list(op.args)
         if op.result is not None:
             args.append(self.getcolor(op.result))
         self.emitline(op.opname, *args)

Added: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- (empty file)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	Wed Apr 21 16:12:21 2010
@@ -0,0 +1,34 @@
+from pypy.rpython.lltypesystem import lltype
+
+
+def transform_graph(graph):
+    """Transform a control flow graph to make it suitable for
+    being flattened in a JitCode.
+    """
+    for block in graph.iterblocks():
+        optimize_goto_if_not(block)
+
+
+def optimize_goto_if_not(block):
+    """Replace code like 'v = int_gt(x,y); exitswitch = v'
+       with just 'exitswitch = ('int_gt',x,y)'."""
+    if len(block.exits) != 2:
+        return False
+    v = block.exitswitch
+    if v.concretetype != lltype.Bool:
+        return False
+    for link in block.exits:
+        if v in link.args:
+            return False   # variable escapes to next block
+    for op in block.operations[::-1]:
+        if v in op.args:
+            return False   # variable is also used in cur block
+        if v is op.result:
+            if op.opname not in ('int_lt', 'int_le', 'int_eq', 'int_ne',
+                                 'int_gt', 'int_ge'):
+                return False    # not a supported operation
+            # ok! optimize this case
+            block.operations.remove(op)
+            block.exitswitch = (op.opname,) + tuple(op.args)
+            return True
+    return False

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	Wed Apr 21 16:12:21 2010
@@ -1,4 +1,5 @@
 from pypy.jit.codewriter.codewriter import CodeWriter
+from pypy.jit.codewriter.blackhole import BlackholeInterpreter
 
 
 def test_loop():
@@ -9,15 +10,28 @@
         return b
     cw = CodeWriter()
     jitcode = cw.transform_func_to_jitcode(f, [5, 6])
-    assert jitcode.code == ("\x00\x00\x00\x02"
-                            "\x01\x13\x00\x02"
-                            "\x02\x01\x00\x01"
-                            "\x03\x00\x01\x00"
-                            "\x04\x00\x00"
-                            "\x05\x01")
-    assert cw.assembler.insns == {'int_gt/ici': 0,
-                                  'goto_if_not/Li': 1,
-                                  'int_add/iii': 2,
-                                  'int_sub/ici': 3,
-                                  'goto/L': 4,
-                                  'int_return/i': 5}
+    assert jitcode.code == ("\x00\x10\x00\x00\x00"
+                            "\x01\x01\x00\x01"
+                            "\x02\x00\x01\x00"
+                            "\x03\x00\x00"
+                            "\x04\x01")
+    assert cw.assembler.insns == {'goto_if_not_int_gt/Lic': 0,
+                                  'int_add/iii': 1,
+                                  'int_sub/ici': 2,
+                                  'goto/L': 3,
+                                  'int_return/i': 4}
+
+def test_integration():
+    def f(a, b):
+        while a > 2:
+            b += a
+            a -= 1
+        return b
+    cw = CodeWriter()
+    jitcode = cw.transform_func_to_jitcode(f, [5, 6])
+    blackholeinterp = BlackholeInterpreter()
+    blackholeinterp.setup_insns(cw.assembler.insns)
+    blackholeinterp.setarg_i(0, 6)
+    blackholeinterp.setarg_i(1, 100)
+    blackholeinterp.run(jitcode, 0)
+    assert blackholeinterp.result_i == 100+6+5+4+3

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	Wed Apr 21 16:12:21 2010
@@ -2,6 +2,7 @@
 from pypy.jit.codewriter import support
 from pypy.jit.codewriter.flatten import flatten_graph, reorder_renaming_list
 from pypy.jit.codewriter.format import format_assembler
+from pypy.jit.codewriter.jitter import transform_graph
 
 
 class FakeRegAlloc:
@@ -34,8 +35,10 @@
         self.rtyper = support.annotate(func, values, type_system=type_system)
         return self.rtyper.annotator.translator.graphs
 
-    def encoding_test(self, func, args, expected, optimize=True):
+    def encoding_test(self, func, args, expected, optimize=False):
         graphs = self.make_graphs(func, args)
+        if optimize:
+            transform_graph(graphs[0])
         ssarepr = flatten_graph(graphs[0], {'int': FakeRegAlloc(),
                                             'ref': FakeRegAlloc(),
                                             'float': FakeRegAlloc()})
@@ -74,6 +77,28 @@
             int_return %i3
         """)
 
+    def test_loop_opt(self):
+        def f(a, b):
+            while a > 0:
+                b += a
+                a -= 1
+            return b
+        self.encoding_test(f, [5, 6], """
+            int_copy %i0, %i2
+            int_copy %i1, %i3
+            L1:
+            goto_if_not_int_gt L2, %i2, $0
+            int_copy %i2, %i4
+            int_copy %i3, %i5
+            int_add %i5, %i4, %i6
+            int_sub %i4, $1, %i7
+            int_copy %i7, %i2
+            int_copy %i6, %i3
+            goto L1
+            L2:
+            int_return %i3
+        """, optimize=True)
+
     def test_float(self):
         def f(i, f):
             return (i*5) + (f*0.25)

Added: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- (empty file)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	Wed Apr 21 16:12:21 2010
@@ -0,0 +1,49 @@
+from pypy.objspace.flow.model import FunctionGraph, Block, Link
+from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
+from pypy.jit.codewriter import jitter
+from pypy.rpython.lltypesystem import lltype
+
+class FakeLink:
+    args = []
+
+def test_optimize_goto_if_not():
+    v1 = Variable()
+    v2 = Variable()
+    v3 = Variable(); v3.concretetype = lltype.Bool
+    sp1 = SpaceOperation('foobar', [], None)
+    sp2 = SpaceOperation('foobaz', [], None)
+    block = Block([v1, v2])
+    block.operations = [sp1, SpaceOperation('int_gt', [v1, v2], v3), sp2]
+    block.exitswitch = v3
+    block.exits = exits = [FakeLink(), FakeLink()]
+    res = jitter.optimize_goto_if_not(block)
+    assert res == True
+    assert block.operations == [sp1, sp2]
+    assert block.exitswitch == ('int_gt', v1, v2)
+    assert block.exits == exits
+
+def test_optimize_goto_if_not__incoming():
+    v1 = Variable(); v1.concretetype = lltype.Bool
+    block = Block([v1])
+    block.exitswitch = v1
+    block.exits = [FakeLink(), FakeLink()]
+    assert not jitter.optimize_goto_if_not(block)
+
+def test_optimize_goto_if_not__exit():
+    v1 = Variable()
+    v2 = Variable()
+    v3 = Variable(); v3.concretetype = lltype.Bool
+    block = Block([v1, v2])
+    block.operations = [SpaceOperation('int_gt', [v1, v2], v3)]
+    block.exitswitch = v3
+    block.exits = [FakeLink(), FakeLink()]
+    block.exits[1].args = [v3]
+    assert not jitter.optimize_goto_if_not(block)
+
+def test_optimize_goto_if_not__unknownop():
+    v3 = Variable(); v3.concretetype = lltype.Bool
+    block = Block([])
+    block.operations = [SpaceOperation('foobar', [], v3)]
+    block.exitswitch = v3
+    block.exits = [FakeLink(), FakeLink()]
+    assert not jitter.optimize_goto_if_not(block)



More information about the Pypy-commit mailing list