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

arigo at codespeak.net arigo at codespeak.net
Fri Jul 28 14:06:35 CEST 2006


Author: arigo
Date: Fri Jul 28 14:06:33 2006
New Revision: 30683

Modified:
   pypy/dist/pypy/translator/simplify.py
   pypy/dist/pypy/translator/test/test_simplify.py
Log:
Bug in transform_dead_op_vars: calls to graphs with no other side effect
than raising an exception were killed!



Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py	(original)
+++ pypy/dist/pypy/translator/simplify.py	Fri Jul 28 14:06:33 2006
@@ -385,14 +385,10 @@
 # _____________________________________________________________________
 # decide whether a function has side effects
 
-class HasSideEffects(Exception):
-    pass
-
 def op_has_side_effects(op):
     return lloperation.LL_OPERATIONS[op.opname].sideeffects
 
-def has_no_side_effects(translator, graph, seen=None,
-                        is_operation_false=op_has_side_effects):
+def has_no_side_effects(translator, graph, seen=None):
     #is the graph specialized? if no we can't say anything
     #don't cache the result though
     if translator.rtyper is None:
@@ -406,31 +402,26 @@
         return True
     newseen = seen.copy()
     newseen[graph] = True
-    try:
-        def visit(block):
-            if not isinstance(block, Block):
-                return
-            for op in block.operations:
-                if op.opname == "direct_call":
-                    g = get_graph(op.args[0], translator)
-                    if g is None:
-                        raise HasSideEffects
+    for block in graph.iterblocks():
+        if block is graph.exceptblock:
+            return False     # graphs explicitly raising have side-effects
+        for op in block.operations:
+            if op.opname == "direct_call":
+                g = get_graph(op.args[0], translator)
+                if g is None:
+                    return False
+                if not has_no_side_effects(translator, g, newseen):
+                    return False
+            elif op.opname == "indirect_call":
+                graphs = op.args[-1].value
+                if graphs is None:
+                    return False
+                for g in graphs:
                     if not has_no_side_effects(translator, g, newseen):
-                        raise HasSideEffects
-                elif op.opname == "indirect_call":
-                    graphs = op.args[-1].value
-                    if graphs is None:
-                        raise HasSideEffects
-                    for g in graphs:
-                        if not has_no_side_effects(translator, g, newseen):
-                            raise HasSideEffects
-                elif is_operation_false(op):
-                    raise HasSideEffects
-        traverse(visit, graph)
-    except HasSideEffects:
-        return False
-    else:
-        return True
+                        return False
+            elif op_has_side_effects(op):
+                return False
+    return True
 
 # ___________________________________________________________________________
 # remove operations if their result is not used and they have no side effects

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	Fri Jul 28 14:06:33 2006
@@ -1,6 +1,7 @@
+import py
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.translator.backendopt.all import backend_optimizations
-from pypy.translator.simplify import get_graph
+from pypy.translator.simplify import get_graph, transform_dead_op_vars
 from pypy.objspace.flow.model import traverse, Block
 
 def translate(func, argtypes, backend_optimize=True):
@@ -172,3 +173,17 @@
     # does not crash: previously join_blocks would barf on this
     remove_same_as(graph)
     backend_optimizations(t)
+
+def test_transform_dead_op_vars_bug():
+    from pypy.rpython.llinterp import LLInterpreter, LLException
+    exc = ValueError()
+    def f1():
+        raise exc     # this function used to be considered side-effects-free
+    def f2():
+        f1()          # <- so this call was removed
+
+    graph, t = translate(f2, [], backend_optimize=False)
+    transform_dead_op_vars(graph, t)
+    interp = LLInterpreter(t.rtyper)
+    e = py.test.raises(LLException, 'interp.eval_graph(graph, [])')
+    assert 'ValueError' in str(e)



More information about the Pypy-commit mailing list