[pypy-commit] pypy core-only-tracing: implement the 'fast' jit mode, in which we trace only inside the 'core' graphs, and do residual calls to everything else; still in-progress, at least one case is missing, see next checkin
antocuni
noreply at buildbot.pypy.org
Fri Jan 20 15:35:14 CET 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: core-only-tracing
Changeset: r51529:927230d64a20
Date: 2012-01-20 14:12 +0100
http://bitbucket.org/pypy/pypy/changeset/927230d64a20/
Log: implement the 'fast' jit mode, in which we trace only inside the
'core' graphs, and do residual calls to everything else; still in-
progress, at least one case is missing, see next checkin
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -778,15 +778,30 @@
result = vinfo.get_array_length(virtualizable, arrayindex)
return ConstInt(result)
+ def perform_call_maybe(self, jitcode, argboxes):
+ core_only_mode = (self.metainterp.jitdriver_sd.warmstate.jitmode == 'fast')
+ if core_only_mode and self.jitcode.is_core:
+ # never inline in this mode
+ funcbox = ConstInt(jitcode.get_fnaddr_as_int())
+ # jitcode always has a calldescr, but it might not have the
+ # correct effectinfo. The result is that we might generate a
+ # call_may_force when a call might suffice; however, we don't care
+ # too much because for the PyPy interpreter most calls are to
+ # space.*, so they would be call_may_force anyway.
+ calldescr = jitcode.calldescr
+ return self.do_residual_call(funcbox, calldescr, argboxes)
+ # normal mode
+ return self.metainterp.perform_call(jitcode, argboxes)
+
@arguments("jitcode", "boxes")
def _opimpl_inline_call1(self, jitcode, argboxes):
- return self.metainterp.perform_call(jitcode, argboxes)
+ return self.perform_call_maybe(jitcode, argboxes)
@arguments("jitcode", "boxes2")
def _opimpl_inline_call2(self, jitcode, argboxes):
- return self.metainterp.perform_call(jitcode, argboxes)
+ return self.perform_call_maybe(jitcode, argboxes)
@arguments("jitcode", "boxes3")
def _opimpl_inline_call3(self, jitcode, argboxes):
- return self.metainterp.perform_call(jitcode, argboxes)
+ return self.perform_call_maybe(jitcode, argboxes)
opimpl_inline_call_r_i = _opimpl_inline_call1
opimpl_inline_call_r_r = _opimpl_inline_call1
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2942,6 +2942,39 @@
res = self.meta_interp(f, [32])
assert res == f(32)
+ def test_residual_call_from_core_graph(self):
+ class MyPolicy(JitPolicy):
+ def is_core_graph(self, graph):
+ return graph.name == 'f'
+ myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
+
+ def a(x):
+ return x
+ def b(x, y):
+ return x+y
+ def c(x, y, z):
+ return x+y+z
+ def f(x, y):
+ res = 0
+ while y > 0:
+ myjitdriver.can_enter_jit(x=x, y=y, res=res)
+ myjitdriver.jit_merge_point(x=x, y=y, res=res)
+ res = a(x) + b(x, res) + c(x, -x, -x) # at the end, it's like doing x+res :-)
+ y -= 1
+ return res
+ res = self.meta_interp(f, [6, 7], policy=MyPolicy(), jitmode='fast') # fast == trace only core graphs
+ assert res == 42
+ self.check_trace_count(1)
+ # this is suboptimal because we get a call_may_force instead of a
+ # call. Look at the comment inside pyjitpl...perform_call_maybe for
+ # details
+ self.check_resops({'jump': 1, 'int_gt': 2, 'guard_true': 2, 'int_sub': 2,
+ 'int_neg': 1, 'int_add': 4,
+ 'call_may_force': 6,
+ 'guard_no_exception': 6,
+ 'guard_not_forced': 6})
+
+
class TestOOtype(BasicTests, OOJitMixin):
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
@@ -67,7 +67,8 @@
backendopt=False, trace_limit=sys.maxint,
inline=False, loop_longevity=0, retrace_limit=5,
function_threshold=4,
- enable_opts=ALL_OPTS_NAMES, max_retrace_guards=15, **kwds):
+ enable_opts=ALL_OPTS_NAMES, max_retrace_guards=15,
+ jitmode='full', **kwds):
from pypy.config.config import ConfigError
translator = interp.typer.annotator.translator
try:
@@ -92,6 +93,7 @@
jd.warmstate.set_param_loop_longevity(loop_longevity)
jd.warmstate.set_param_retrace_limit(retrace_limit)
jd.warmstate.set_param_max_retrace_guards(max_retrace_guards)
+ jd.warmstate.set_param_jitmode(jitmode)
jd.warmstate.set_param_enable_opts(enable_opts)
warmrunnerdesc.finish()
if graph_and_interp_only:
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -213,6 +213,9 @@
def set_param_inlining(self, value):
self.inlining = value
+ def set_param_jitmode(self, value):
+ self.jitmode = value
+
def set_param_enable_opts(self, value):
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT, ALL_OPTS_NAMES
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -402,6 +402,7 @@
'retrace_limit': 'how many times we can try retracing before giving up',
'max_retrace_guards': 'number of extra guards a retrace can cause',
'max_unroll_loops': 'number of extra unrollings a loop can cause',
+ 'jitmode': '"full" (default) or "fast"',
'enable_opts': 'optimizations to enable or all, INTERNAL USE ONLY'
}
@@ -414,6 +415,7 @@
'retrace_limit': 5,
'max_retrace_guards': 15,
'max_unroll_loops': 4,
+ 'jitmode': 'full',
'enable_opts': 'all',
}
unroll_parameters = unrolling_iterable(PARAMETERS.items())
More information about the pypy-commit
mailing list