[pypy-svn] r18192 - in pypy/dist/pypy/translator: backendopt backendopt/test tool
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 5 14:03:25 CEST 2005
Author: arigo
Date: Wed Oct 5 14:03:20 2005
New Revision: 18192
Modified:
pypy/dist/pypy/translator/backendopt/inline.py
pypy/dist/pypy/translator/backendopt/test/test_inline.py
pypy/dist/pypy/translator/tool/make_dot.py
Log:
(pedronis, arigo) Eric pointed out that we can have 'keepalive' as the
operation whose exceptions are caught, which makes no sense. As a result,
found more bugs in inline, old and new.
Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/inline.py Wed Oct 5 14:03:20 2005
@@ -68,6 +68,7 @@
ops[-4].opname != "setfield" or ops[-3].opname != "cast_pointer" or
ops[-2].opname != "getfield" or ops[-1].opname != "cast_pointer" or
len(block.exits) != 1 or block.exits[0].args[0] != ops[-2].result or
+ block.exitswitch is not None or
block.exits[0].args[1] != ops[-1].result or
not isinstance(ops[-4].args[1], Constant) or
ops[-4].args[1].value != "typeptr"):
@@ -201,7 +202,6 @@
#try to match the exceptions for simple cases
for link in entrymap[graph_to_inline.exceptblock]:
copiedblock = copied_blocks[link.prevblock]
- copiedblock.operations += generate_keepalive(passon_vars[link.prevblock])
copiedlink = copiedblock.exits[0]
eclass = _find_exception_type(copiedblock)
#print copiedblock.operations
@@ -211,6 +211,8 @@
evalue = copiedlink.args[1]
for exceptionlink in afterblock.exits[1:]:
if exc_match.value(eclass, exceptionlink.llexitcase):
+ copiedblock.operations += generate_keepalive(
+ passon_vars[link.prevblock])
copiedlink.target = exceptionlink.target
linkargs = find_args_in_exceptional_case(exceptionlink,
link.prevblock,
@@ -249,13 +251,18 @@
blocks[-1].exits = blocks[-1].exits[:1]
blocks[-1].operations = []
blocks[-1].exitswitch = None
+ blocks[-1].exits[0].exitcase = None
+ del blocks[-1].exits[0].llexitcase
linkargs = copiedexceptblock.inputargs
copiedexceptblock.closeblock(Link(linkargs, blocks[0]))
copiedexceptblock.operations += generate_keepalive(linkargs)
- afterblock.exits = [afterblock.exits[0]]
- afterblock.exitswitch = None
+ if exception_guarded:
+ assert afterblock.exits[0].exitcase is None
+ afterblock.exits = [afterblock.exits[0]]
+ afterblock.exitswitch = None
#cleaning up -- makes sense to be here, because I insert quite
#some empty blocks and blocks that can be joined
+ checkgraph(graph)
eliminate_empty_blocks(graph)
join_blocks(graph)
remove_identical_vars(graph)
Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Wed Oct 5 14:03:20 2005
@@ -1,12 +1,14 @@
import py
import os
from pypy.objspace.flow.model import traverse, Block, Link, Variable, Constant
+from pypy.objspace.flow.model import last_exception, checkgraph
from pypy.translator.backendopt.inline import inline_function, CannotInline
from pypy.translator.backendopt.inline import auto_inlining
from pypy.translator.backendopt.inline import collect_called_functions
from pypy.translator.backendopt.inline import measure_median_execution_cost
from pypy.translator.translator import Translator
from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.rarithmetic import ovfcheck
from pypy.translator.test.snippet import is_perfect_number
def no_missing_concretetype(node):
@@ -27,19 +29,21 @@
if isinstance(node.last_exc_value, (Variable, Constant)):
assert hasattr(node.last_exc_value, 'concretetype')
+def sanity_check(t):
+ # look for missing '.concretetype'
+ for graph in t.flowgraphs.values():
+ checkgraph(graph)
+ traverse(no_missing_concretetype, graph)
+
def check_inline(func, in_func, sig):
t = Translator(in_func)
a = t.annotate(sig)
a.simplify()
t.specialize()
- # look for missing '.concretetype' before inlining (so we don't blame it)
- for graph in t.flowgraphs.values():
- traverse(no_missing_concretetype, graph)
# inline!
+ sanity_check(t) # also check before inlining (so we don't blame it)
inline_function(t, func, t.flowgraphs[in_func])
- # look for missing '.concretetype'
- for graph in t.flowgraphs.values():
- traverse(no_missing_concretetype, graph)
+ sanity_check(t)
interp = LLInterpreter(t.flowgraphs, t.rtyper)
return interp
@@ -90,7 +94,9 @@
a = t.annotate([int])
a.simplify()
t.specialize()
+ sanity_check(t) # also check before inlining (so we don't blame it)
inline_function(t, f, t.flowgraphs[g])
+ sanity_check(t)
interp = LLInterpreter(t.flowgraphs, t.rtyper)
result = interp.eval_function(h, [0])
assert result == 0
@@ -168,6 +174,18 @@
result = interp.eval_function(g, [42])
assert result == 1
+def test_inline_nonraising_into_catching():
+ def f(x):
+ return x+1
+ def g(x):
+ try:
+ return f(x)
+ except KeyError:
+ return 42
+ interp = check_inline(f, g, [int])
+ result = interp.eval_function(g, [7654])
+ assert result == 7655
+
def DONOTtest_call_call():
# for reference. Just remove this test if we decide not to support
# catching exceptions while inlining a graph that contains further
@@ -187,7 +205,9 @@
a = t.annotate([int])
a.simplify()
t.specialize()
+ sanity_check(t) # also check before inlining (so we don't blame it)
inline_function(t, f, t.flowgraphs[g])
+ sanity_check(t)
interp = LLInterpreter(t.flowgraphs, t.rtyper)
result = interp.eval_function(g, [100])
assert result == 106
@@ -209,7 +229,9 @@
break
else:
assert 0, "cannot find ll_rangenext_*() function"
+ sanity_check(t) # also check before inlining (so we don't blame it)
inline_function(t, graph, t.flowgraphs[f])
+ sanity_check(t)
interp = LLInterpreter(t.flowgraphs, t.rtyper)
result = interp.eval_function(f, [10])
assert result == 45
@@ -282,6 +304,22 @@
result = interp.eval_function(f, [])
assert result is True
+def test_inline_catching_different_exception():
+ d = {1: 2}
+ def f2(n):
+ try:
+ return ovfcheck(n+1)
+ except OverflowError:
+ raise
+ def f(n):
+ try:
+ return f2(n)
+ except ValueError:
+ return -1
+ interp = check_inline(f2, f, [int])
+ result = interp.eval_function(f, [54])
+ assert result == 55
+
def test_auto_inline_os_path_isdir():
directory = "./."
def f():
Modified: pypy/dist/pypy/translator/tool/make_dot.py
==============================================================================
--- pypy/dist/pypy/translator/tool/make_dot.py (original)
+++ pypy/dist/pypy/translator/tool/make_dot.py Wed Oct 5 14:03:20 2005
@@ -134,9 +134,11 @@
shape = "box"
else:
color = "red"
- lines.append("exitswitch: %s" % block.exitswitch)
shape = "octagon"
+ if block.exitswitch is not None:
+ lines.append("exitswitch: %s" % block.exitswitch)
+
iargs = " ".join(map(repr, block.inputargs))
if block.exc_handler:
eh = 'EH'
@@ -164,16 +166,14 @@
self.emit_node(name, label=data, shape=shape, color=color, style="filled", fillcolor=fillcolor)
# do links/exits
- if numblocks == 1:
- name2 = self.blockname(block.exits[0].target)
- label = " ".join(map(repr, block.exits[0].args))
- self.emit_edge(name, name2, label, style="solid")
- elif numblocks >1:
- for link in block.exits:
- name2 = self.blockname(link.target)
- label = " ".join(map(repr, link.args))
+ for link in block.exits:
+ name2 = self.blockname(link.target)
+ label = " ".join(map(repr, link.args))
+ if link.exitcase is not None:
label = "%s: %s" %(link.exitcase, label)
- self.emit_edge(name, name2, label, style="dotted", color=color)
+ self.emit_edge(name, name2, label, style="dotted", color="red")
+ else:
+ self.emit_edge(name, name2, label, style="solid")
def make_dot(graphname, graph, storedir=None, target='ps'):
More information about the Pypy-commit
mailing list