[pypy-commit] pypy jit-limit_peeling: Only unrol if the peeled loop is shorter than the preamble. Add a limit_peeling parameter to control how much shorter.
hakanardo
noreply at buildbot.pypy.org
Fri Aug 19 19:16:14 CEST 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-limit_peeling
Changeset: r46646:7fc5d9611d13
Date: 2011-08-19 19:20 +0200
http://bitbucket.org/pypy/pypy/changeset/7fc5d9611d13/
Log: Only unrol if the peeled loop is shorter than the preamble. Add a
limit_peeling parameter to control how much shorter.
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -324,6 +324,7 @@
class memory_manager:
retrace_limit = 5
max_retrace_guards = 15
+ limit_peeling = 0
class Storage(compile.ResumeGuardDescr):
"for tests."
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -205,6 +205,17 @@
short = self.inline(inputargs, self.cloned_operations,
loop.inputargs, short_inputargs,
virtual_state)
+ if not virtual_state.contains_virtuals():
+ ops_in_loop = len(self.optimizer.newoperations)
+ ops_in_preamble = len(loop.preamble.operations) + 1
+ amount_saved = ((ops_in_preamble - ops_in_loop) * 100) / ops_in_preamble
+ th = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.limit_peeling
+ if amount_saved <= th:
+ jumpop.initarglist(jump_args)
+ loop.preamble.operations.append(jumpop)
+ loop.operations = loop.preamble.operations
+ loop.preamble.operations = None
+ return
loop.inputargs = inputargs
args = [preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box()\
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -401,6 +401,12 @@
for s in self.state:
s.debug_print(" ", seen, bad)
+ def contains_virtuals(self):
+ for s in self.state:
+ if not isinstance(s, NotVirtualStateInfo):
+ return True
+ return False
+
class VirtualStateAdder(resume.ResumeDataVirtualAdder):
def __init__(self, optimizer):
self.fieldboxes = {}
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
@@ -2637,6 +2637,25 @@
assert self.meta_interp(f, [20, 10]) == f(20, 10)
self.check_tree_loop_count(5)
+ def test_limit_peeling(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
+
+ def f(n, limit):
+ myjitdriver.set_param('limit_peeling', limit)
+ sa = i = 0
+ a = n + 1
+ while i < n:
+ myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a)
+ sa += a * a
+ i += 1
+ return sa
+ assert self.meta_interp(f, [20, 0]) == f(20, 0)
+ self.check_tree_loop_count(2)
+ assert self.meta_interp(f, [20, 10]) == f(20, 10)
+ self.check_tree_loop_count(2)
+ assert self.meta_interp(f, [20, 20]) == f(20, 20)
+ self.check_tree_loop_count(1)
+
def test_retrace_limit_with_extra_guards(self):
myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a',
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
@@ -63,7 +63,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,
+ limit_peeling=0, **kwds):
from pypy.config.config import ConfigError
translator = interp.typer.annotator.translator
try:
@@ -87,6 +88,7 @@
jd.warmstate.set_param_inlining(inline)
jd.warmstate.set_param_loop_longevity(loop_longevity)
jd.warmstate.set_param_retrace_limit(retrace_limit)
+ jd.warmstate.set_param_limit_peeling(limit_peeling)
jd.warmstate.set_param_max_retrace_guards(max_retrace_guards)
jd.warmstate.set_param_enable_opts(enable_opts)
warmrunnerdesc.finish()
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
@@ -275,6 +275,11 @@
if self.warmrunnerdesc.memory_manager:
self.warmrunnerdesc.memory_manager.max_retrace_guards = value
+ def set_param_limit_peeling(self, value):
+ if self.warmrunnerdesc:
+ if self.warmrunnerdesc.memory_manager:
+ self.warmrunnerdesc.memory_manager.limit_peeling = value
+
def disable_noninlinable_function(self, greenkey):
cell = self.jit_cell_at_key(greenkey)
cell.dont_trace_here = True
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -299,6 +299,7 @@
'loop_longevity': 1000,
'retrace_limit': 5,
'max_retrace_guards': 15,
+ 'limit_peeling': 0,
'enable_opts': 'all',
}
unroll_parameters = unrolling_iterable(PARAMETERS.items())
More information about the pypy-commit
mailing list