Author: Remi Meier <[email protected]>
Branch: guard-compatible
Changeset: r94036:931f5eaed82f
Date: 2018-03-20 17:18 +0100
http://bitbucket.org/pypy/pypy/changeset/931f5eaed82f/
Log: (arigo, remi) test and fix a case of too many bridges
see test for explanation
diff --git a/rpython/jit/metainterp/blackhole.py
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1,6 +1,5 @@
from rpython.jit.codewriter import heaptracker, longlong
from rpython.jit.codewriter.jitcode import JitCode, SwitchDictDescr
-from rpython.jit.metainterp.compile import ResumeAtPositionDescr
from rpython.jit.metainterp.jitexc import get_llexception, reraise
from rpython.jit.metainterp import jitexc
from rpython.jit.metainterp.history import MissingValue
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -692,6 +692,8 @@
class ResumeDescr(AbstractFailDescr):
_attrs_ = ()
+ resume_at_loop_start = False
+
def clone(self):
return self
@@ -901,7 +903,7 @@
pass
class ResumeAtPositionDescr(ResumeGuardDescr):
- pass
+ resume_at_loop_start = True
class CompileLoopVersionDescr(ResumeGuardDescr):
def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
@@ -1062,7 +1064,7 @@
metainterp_sd.jitlog.start_new_trace(metainterp_sd,
faildescr=resumekey, entry_bridge=False, jd_name=jd_name)
#
- if isinstance(resumekey, ResumeAtPositionDescr):
+ if resumekey.resume_at_loop_start:
inline_short_preamble = False
else:
inline_short_preamble = True
@@ -1109,6 +1111,7 @@
metainterp.retrace_needed(new_trace, info)
return None
+
class GuardCompatibleDescr(ResumeGuardDescr):
""" A descr for guard_compatible. All the conditions that a value should
fulfil need to be attached to this descr by optimizeopt. """
@@ -1214,6 +1217,10 @@
return []
+class ResumeAtPositionForCompatibleDescr(GuardCompatibleDescr):
+ resume_at_loop_start = True
+
+
# ____________________________________________________________
memory_error = MemoryError()
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -542,8 +542,7 @@
raise InvalidLoop('A GUARD_CLASS (%s) was proven to always fail'
% r)
old_guard_op = info.get_last_guard(self.optimizer)
- if old_guard_op and not isinstance(old_guard_op.getdescr(),
- compile.ResumeAtPositionDescr):
+ if old_guard_op and not old_guard_op.getdescr().resume_at_loop_start:
# there already has been a guard_nonnull or guard_class or
# guard_nonnull_class on this value.
if old_guard_op.getopnum() == rop.GUARD_NONNULL:
@@ -566,8 +565,8 @@
expectedclassbox = op.getarg(1)
info = self.getptrinfo(op.getarg(0))
old_guard_op = info.get_last_guard(self.optimizer)
- update_last_guard = not old_guard_op or isinstance(
- old_guard_op.getdescr(), compile.ResumeAtPositionDescr)
+ update_last_guard = (not old_guard_op or
+ old_guard_op.getdescr().resume_at_loop_start)
self.make_constant_class(op.getarg(0), expectedclassbox,
update_last_guard)
def optimize_GUARD_NONNULL_CLASS(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -342,7 +342,7 @@
if isinstance(guard, GuardResOp):
guard.rd_resume_position =
patchguardop.rd_resume_position
if guard.opnum == rop.GUARD_COMPATIBLE:
- guard.setdescr(compile.GuardCompatibleDescr())
+
guard.setdescr(compile.ResumeAtPositionForCompatibleDescr())
else:
guard.setdescr(compile.ResumeAtPositionDescr())
self.send_extra_operation(guard)
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -2496,7 +2496,7 @@
self.current_merge_points = []
self.resumekey = resumedescr
self.seen_loop_header_for_jdindex = -1
- if isinstance(key, compile.ResumeAtPositionDescr):
+ if key.resume_at_loop_start:
self.seen_loop_header_for_jdindex = self.jitdriver_sd.index
self.prepare_resume_from_failure(deadframe, inputargs, resumedescr)
if self.resumekey_original_loop_token is None: # very rare case
diff --git a/rpython/jit/metainterp/test/test_compatible.py
b/rpython/jit/metainterp/test/test_compatible.py
--- a/rpython/jit/metainterp/test/test_compatible.py
+++ b/rpython/jit/metainterp/test/test_compatible.py
@@ -2,7 +2,6 @@
from rpython.rlib import jit
from rpython.rtyper.lltypesystem import lltype, rffi
-
class TestCompatible(LLJitMixin):
def test_simple(self):
S = lltype.GcStruct('S', ('x', lltype.Signed))
@@ -613,6 +612,59 @@
self.check_resops(call_i=0)
+ def test_short_preamble_resume_at_loop_start(self):
+ """check that an inserted guard_compatible in the short preamble will
always
+ resume at the loop start and not create a bridge (which contains
+ another loop iteration with guards, causing a lot of bridges to
+ appear). Basically do the same as for guard_value in short preambles.
+ """
+ from rpython.rlib.objectmodel import we_are_translated
+
+ class C(object):
+ def __init__(self, x):
+ self.x = x
+
+ p1 = C(1)
+ p1.link = None
+
+ p2 = C(2)
+ p2.link = C(1)
+ p2.link.link = None
+
+ p2a = C(2)
+ p2a.link = C(2)
+ p2a.link.link = C(1)
+
+ driver = jit.JitDriver(greens=[], reds=['n', 'x'])
+
+ @jit.elidable_compatible()
+ def g(o):
+ return o.x
+
+ def f(n, x):
+ res = 0
+ while n > 0:
+ driver.can_enter_jit(n=n, x=x)
+ driver.jit_merge_point(n=n, x=x)
+ x = jit.hint(x, promote_compatible=True)
+ res = g(x)
+ if res == 2:
+ x = x.link
+ n -= res
+ return res
+
+ def main(x):
+ jit.set_param(driver, 'trace_eagerness', 1)
+ res = f(100, p1)
+ res += f(100, p2)
+ res += f(100, p2a)
+ return res
+
+ x = self.meta_interp(main, [False])
+ self.check_trace_count(4)
+ self.check_resops(int_sub=3) # not 4!
+
+
def test_like_objects(self):
from rpython.rlib.objectmodel import we_are_translated
class Map(object):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit