[pypy-commit] pypy guard-compatible: need to try the descrs in order old-to-new
cfbolz
pypy.commits at gmail.com
Tue Mar 22 12:47:39 EDT 2016
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: guard-compatible
Changeset: r83258:8a97958ad065
Date: 2016-03-22 15:26 +0100
http://bitbucket.org/pypy/pypy/changeset/8a97958ad065/
Log: need to try the descrs in order old-to-new
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
@@ -1089,23 +1089,26 @@
# XXX think about what is being kept alive here
self._compatibility_conditions = None
self.failarg_index = -1
- self._prev_guard_compatible_descr = None
+ # list of descrs about the same variable, potentially shared with
+ # subsequent guards in bridges
+ self.guard_descrs_list = [self]
def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
index = intmask(self.status >> self.ST_SHIFT)
typetag = intmask(self.status & self.ST_TYPE_MASK)
assert typetag == self.TY_REF # for now
refval = metainterp_sd.cpu.get_value_direct(deadframe, 'r', index)
- curr = self
- while curr:
+ if not we_are_translated():
+ assert self in self.guard_descrs_list
+ # need to do the checking oldest to newest, to check the most specific
+ # condition first
+ for curr in self.guard_descrs_list:
if curr.is_compatible(metainterp_sd.cpu, refval):
from rpython.jit.metainterp.blackhole import resume_in_blackhole
metainterp_sd.cpu.grow_guard_compatible_switch(
curr.rd_loop_token, curr, refval)
resume_in_blackhole(metainterp_sd, jitdriver_sd, self, deadframe)
return
- # try previous guards, maybe one of them would have matched
- curr = curr._prev_guard_compatible_descr
# a real failure
return ResumeGuardDescr.handle_fail(self, deadframe, metainterp_sd, jitdriver_sd)
@@ -1130,7 +1133,8 @@
# a guard_compatible about the same box
newdescr = firstop.getdescr()
assert isinstance(newdescr, GuardCompatibleDescr)
- newdescr._prev_guard_compatible_descr = self
+ newdescr.guard_descrs_list = self.guard_descrs_list
+ self.guard_descrs_list.append(newdescr)
ResumeGuardDescr.compile_and_attach(
self, metainterp, new_loop, orig_inputargs)
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
@@ -222,3 +222,57 @@
# trace, two bridges, a finish bridge
self.check_trace_count(4)
+
+ def test_order_of_chained_guards(self):
+ class Obj(object):
+ def __init__(self):
+ self.m = Map()
+ class Map(object):
+ pass
+
+ p1 = Obj()
+ p1.m.x = 5
+ p1.m.y = 5
+
+ p2 = Obj()
+ p2.m.x = 5
+ p2.m.y = 5
+
+ p3 = Obj()
+ p3.m.x = 5
+ p3.m.y = 6
+ driver = jit.JitDriver(greens = [], reds = ['n', 'x'])
+
+ class A(object):
+ pass
+
+ c = A()
+ c.count = 0
+ @jit.elidable_compatible()
+ def check1(m, ignored):
+ c.count += 1
+ return m.x
+
+ @jit.elidable_compatible()
+ def check2(m, ignored):
+ c.count += 1
+ return m.y
+
+ def f(n, x):
+ while n > 0:
+ driver.can_enter_jit(n=n, x=x)
+ driver.jit_merge_point(n=n, x=x)
+ n -= check1(x.m, 7) + check2(x.m, 7)
+
+ def main():
+ check1(p1.m, 9) # make annotator not make argument constant
+ f(100, p1)
+ f(100, p3) # not compatible, so make a bridge
+ f(100, p2) # compatible with loop again, too bad
+ return c.count
+
+ x = self.meta_interp(main, [])
+
+ # trace, two bridges, a finish bridge
+ self.check_trace_count(4)
+ assert x < 50
More information about the pypy-commit
mailing list