[pypy-svn] r25786 - in pypy/dist/pypy/translator: . backendopt test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Apr 13 14:53:25 CEST 2006


Author: cfbolz
Date: Thu Apr 13 14:53:24 2006
New Revision: 25786

Modified:
   pypy/dist/pypy/translator/backendopt/removenoops.py
   pypy/dist/pypy/translator/simplify.py
   pypy/dist/pypy/translator/test/test_simplify.py
Log:
fix a rarely occuring bug in join_blocks: if the exitswitch of the second block
was a constant in eh link coming from the first block, the exits of the second
block would not be properly pruned. Also remove some op.cleanup leftovers as
well as some visit usages in removenoops.


Modified: pypy/dist/pypy/translator/backendopt/removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/removenoops.py	(original)
+++ pypy/dist/pypy/translator/backendopt/removenoops.py	Thu Apr 13 14:53:24 2006
@@ -9,12 +9,10 @@
     """Removes unary low-level ops with a name appearing in the opnames list.
     """
     positions = []
-    def visit(node): 
-        if isinstance(node, Block): 
-            for i, op in enumerate(node.operations):
-                if op.opname in opnames:
-                    positions.append((node, i))
-    traverse(visit, graph)
+    for block in graph.iterblocks():
+        for i, op in enumerate(block.operations):
+            if op.opname in opnames:
+                positions.append((block, i))
     while positions:
         block, index = positions.pop()
         op_result = block.operations[index].result
@@ -34,22 +32,13 @@
             if isinstance(op_arg, Variable):
                 block.exitswitch = op_arg
             else:
-                assert isinstance(op_arg, Constant)
-                newexits = [link for link in block.exits
-                                 if link.exitcase == op_arg.value]
-                assert len(newexits) == 1
-                newexits[0].exitcase = None
-                if hasattr(newexits[0], 'llexitcase'):
-                    newexits[0].llexitcase = None
-                block.exitswitch = None
-                block.recloseblock(*newexits)
+                simplify.replace_exitswitch_by_constant(block, op_arg)
         block.operations[index] = None
        
     # remove all operations
-    def visit(node): 
-        if isinstance(node, Block) and node.operations:
-            node.operations[:] = filter(None, node.operations)
-    traverse(visit, graph)
+    for block in graph.iterblocks():
+        if block.operations:
+            block.operations[:] = filter(None, block.operations)
 
 def remove_same_as(graph):
     remove_unaryops(graph, ["same_as"])

Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py	(original)
+++ pypy/dist/pypy/translator/simplify.py	Thu Apr 13 14:53:24 2006
@@ -37,6 +37,18 @@
         return None
 
 
+def replace_exitswitch_by_constant(block, const):
+    assert isinstance(const, Constant)
+    assert const != c_last_exception
+    newexits = [link for link in block.exits
+                     if link.exitcase == const.value]
+    assert len(newexits) == 1
+    newexits[0].exitcase = None
+    if hasattr(newexits[0], 'llexitcase'):
+        newexits[0].llexitcase = None
+    block.exitswitch = None
+    block.recloseblock(*newexits)
+
 # ____________________________________________________________
 
 def eliminate_empty_blocks(graph):
@@ -303,26 +315,13 @@
             len(entrymap[link.target]) == 1 and
             link.target.exits):  # stop at the returnblock
             renaming = {}
-            cache_cleanups = {}
             for vprev, vtarg in zip(link.args, link.target.inputargs):
                 renaming[vtarg] = vprev
             def rename(v):
                 return renaming.get(v, v)
             def rename_op(op):
                 args = [rename(a) for a in op.args]
-                if hasattr(op, "cleanup"):
-                    if op.cleanup is None:
-                        cleanup = None
-                    elif op.cleanup not in cache_cleanups:
-                        finallyops, exceptops = op.cleanup
-                        cleanup = (tuple([rename_op(fo) for fo in finallyops]),
-                                   tuple([rename_op(eo) for eo in exceptops]))
-                        cache_cleanups[op.cleanup] = cleanup
-                    else:
-                        cleanup = cache_cleanups[op.cleanup] 
-                    op = SpaceOperation(op.opname, args, rename(op.result), cleanup=cleanup)
-                else:
-                    op = SpaceOperation(op.opname, args, rename(op.result))
+                op = SpaceOperation(op.opname, args, rename(op.result))
                 return op
             for op in link.target.operations:
                 link.prevblock.operations.append(rename_op(op))
@@ -330,8 +329,11 @@
             for exit in link.target.exits:
                 newexit = exit.copy(rename)
                 exits.append(newexit)
-            link.prevblock.exitswitch = rename(link.target.exitswitch)
+            newexitswitch = rename(link.target.exitswitch)
+            link.prevblock.exitswitch = newexitswitch
             link.prevblock.recloseblock(*exits)
+            if isinstance(newexitswitch, Constant) and newexitswitch != c_last_exception:
+                replace_exitswitch_by_constant(link.prevblock, newexitswitch)
             stack.extend(exits)
         else:
             if link.target not in seen:

Modified: pypy/dist/pypy/translator/test/test_simplify.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_simplify.py	(original)
+++ pypy/dist/pypy/translator/test/test_simplify.py	Thu Apr 13 14:53:24 2006
@@ -154,3 +154,21 @@
     assert g(1) == 1001
     # does not crash: previously join_blocks would barf on this
     graph, t = translate(g, [int])
+
+def test_join_blocks_cleans_links():
+    from pypy.rpython.lltypesystem import lltype
+    from pypy.objspace.flow.model import Constant
+    from pypy.translator.backendopt.removenoops import remove_same_as
+    def f(x):
+        return bool(x + 2)
+    def g(x):
+        if f(x):
+            return 1
+        else:
+            return 2
+    graph, t = translate(g, [int], backend_optimize=False)
+    fgraph = graphof(t, f)
+    fgraph.startblock.exits[0].args = [Constant(True, lltype.Bool)]
+    # does not crash: previously join_blocks would barf on this
+    remove_same_as(graph)
+    backend_optimizations(t)



More information about the Pypy-commit mailing list