[pypy-svn] r21787 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Jan 7 15:13:59 CET 2006
Author: cfbolz
Date: Sat Jan 7 15:13:58 2006
New Revision: 21787
Modified:
pypy/dist/pypy/translator/backendopt/inline.py
pypy/dist/pypy/translator/backendopt/test/test_inline.py
Log:
fix inlining after indirect_call refactoring (thanks samuele for the hint). Now
collect_called_graphs tries hard to return all graphs of a function (which is
not actually used in inlining but potentially nice). Test for the bug.
Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/inline.py Sat Jan 7 15:13:58 2006
@@ -1,6 +1,6 @@
import sys
from pypy.translator.simplify import eliminate_empty_blocks, join_blocks
-from pypy.translator.simplify import remove_identical_vars
+from pypy.translator.simplify import remove_identical_vars, get_graph
from pypy.translator.unsimplify import copyvar, split_block
from pypy.objspace.flow.model import Variable, Constant, Block, Link
from pypy.objspace.flow.model import SpaceOperation, c_last_exception
@@ -18,16 +18,24 @@
pass
-def collect_called_functions(graph):
- funcs = {}
- def visit(obj):
- if not isinstance(obj, Block):
- return
- for op in obj.operations:
+def collect_called_graphs(graph, translator):
+ graphs_or_something = {}
+ for block in graph.iterblocks():
+ for op in block.operations:
if op.opname == "direct_call":
- funcs[op.args[0]] = True
- traverse(visit, graph)
- return funcs
+ graph = get_graph(op.args[0], translator)
+ if graph is not None:
+ graphs_or_something[graph] = True
+ else:
+ graphs_or_something[op.args[0]] = True
+ if op.opname == "indirect_call":
+ graphs = op.args[-1].value
+ if graphs is None:
+ graphs_or_something[op.args[0]] = True
+ else:
+ for graph in graphs:
+ graphs_or_something[graph] = True
+ return graphs_or_something
def find_callsites(graph, calling_what):
callsites = []
@@ -81,7 +89,7 @@
if (block.exitswitch == c_last_exception and
index_operation == len(block.operations) - 1):
exception_guarded = True
- if len(collect_called_functions(graph_to_inline)) != 0:
+ if len(collect_called_graphs(graph_to_inline, translator)) != 0:
raise CannotInline("can't handle exceptions yet")
entrymap = mkentrymap(graph_to_inline)
beforeblock = block
@@ -277,6 +285,7 @@
'cast_pointer': 0,
'keepalive': 0,
'direct_call': 2, # guess
+ 'indirect_call': 2, # guess
'yield_current_frame_to_caller': sys.maxint, # XXX bit extreme
}
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 Sat Jan 7 15:13:58 2006
@@ -5,7 +5,7 @@
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 collect_called_graphs
from pypy.translator.backendopt.inline import measure_median_execution_cost
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.llinterp import LLInterpreter
@@ -277,7 +277,7 @@
return -1
eval_func, t = check_auto_inlining(f, [int], threshold=10)
f_graph = graphof(t, f)
- assert len(collect_called_functions(f_graph)) == 0
+ assert len(collect_called_graphs(f_graph, t)) == 0
result = eval_func([10])
assert result == 45
@@ -357,3 +357,27 @@
graph = t.buildflowgraph(f)
res = measure_median_execution_cost(graph)
assert res == 19
+
+def test_indirect_call_with_exception():
+ class MyExc(Exception):
+ pass
+ def x1():
+ return 1
+ def x2():
+ return 2
+ def x3(x):
+ if x:
+ f = x1
+ else:
+ f = x2
+ return f()
+ def x4():
+ try:
+ x3(0)
+ x3(1)
+ except MyExc:
+ return 0
+ return 1
+ assert x4() == 1
+ py.test.raises(CannotInline, check_inline, x3, x4, [])
+
More information about the Pypy-commit
mailing list