[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