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

Reply via email to