Author: Antonio Cuni <[email protected]>
Branch: autoreds
Changeset: r58918:359bb4af990b
Date: 2012-11-14 23:27 +0100
http://bitbucket.org/pypy/pypy/changeset/359bb4af990b/
Log: a failing test and the fix: it is not enough to manually call
inline_function, we need the full auto_inline logic to correctly
handle calls to graphs which raise exceptions
diff --git a/pypy/jit/metainterp/test/test_warmspot.py
b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -423,6 +423,31 @@
self.check_resops(int_eq=4, int_add=8)
self.check_trace_count(2)
+ def test_inline_in_portal_exception(self):
+ myjitdriver = JitDriver(greens = [], reds = 'auto')
+ def inc(n):
+ if n == 1000:
+ raise OverflowError
+ return n+1
+
+ @myjitdriver.inline_in_portal
+ def jitted_inc(n):
+ myjitdriver.jit_merge_point()
+ return inc(n)
+
+ def f():
+ res = 0
+ while True:
+ try:
+ res = jitted_inc(res)
+ except OverflowError:
+ break
+ return res
+ res = self.meta_interp(f, [])
+ assert res == 1000
+ self.check_resops(int_add=2)
+
+
class TestLLWarmspot(WarmspotTests, LLJitMixin):
CPUClass = runner.LLtypeCPU
type_system = 'lltype'
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -251,20 +251,24 @@
test_ajit::test_inline_in_portal.
"""
from pypy.translator.backendopt import inline
- lltype_to_classdef =
self.translator.rtyper.lltype_to_classdef_mapping()
- raise_analyzer = inline.RaiseAnalyzer(self.translator)
+
+ # find all the graphs which call an @inline_in_portal function
callgraph = inline.inlinable_static_callers(self.translator.graphs)
+ new_callgraph = []
new_portals = set()
for caller, callee in callgraph:
func = getattr(callee, 'func', None)
_inline_in_portal_ = getattr(func, '_inline_in_portal_', False)
if _inline_in_portal_:
- count = inline.inline_function(self.translator, callee, caller,
- lltype_to_classdef,
raise_analyzer)
- assert count > 0, ('The function has been decorated with '
- '@inline_in_portal, but it is not possible '
- 'to inline it')
+ new_callgraph.append((caller, callee))
new_portals.add(caller)
+
+ # inline them!
+ inline_threshold =
self.translator.config.translation.backendopt.inline_threshold
+ inline.auto_inlining(self.translator, inline_threshold, callgraph)
+
+ # make a fresh copy of the JitDriver in all newly created
+ # jit_merge_points
self.clone_inlined_jit_merge_points(new_portals)
def clone_inlined_jit_merge_points(self, graphs):
@@ -277,7 +281,10 @@
for graph, block, pos in find_jit_merge_points(graphs):
op = block.operations[pos]
v_driver = op.args[1]
- new_driver = v_driver.value.clone()
+ driver = v_driver.value
+ if not driver.inlined_in_portal:
+ continue
+ new_driver = driver.clone()
c_new_driver = Constant(new_driver, v_driver.concretetype)
op.args[1] = c_new_driver
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -554,6 +554,7 @@
def inline_in_portal(self, func):
assert self.autoreds, "inline_in_portal works only with reds='auto'"
func._inline_in_portal_ = True
+ func._always_inline_ = True
self.inlined_in_portal = True
return func
diff --git a/pypy/rlib/test/test_jit.py b/pypy/rlib/test/test_jit.py
--- a/pypy/rlib/test/test_jit.py
+++ b/pypy/rlib/test/test_jit.py
@@ -47,6 +47,7 @@
py.test.raises(AssertionError, "driver.clone()")
foo = driver.inline_in_portal(foo)
assert foo._inline_in_portal_ == True
+ assert foo._always_inline_ == True
#
driver.foo = 'bar'
driver2 = driver.clone()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit