[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