Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: guard-compatible
Changeset: r85432:f9d5045ab715
Date: 2016-06-27 19:10 +0200
http://bitbucket.org/pypy/pypy/changeset/f9d5045ab715/

Log:    simply call @elidable_compatible functions where we don't have a
        result (this can only happen when inlining the short preamble into a
        bridge)

diff --git a/rpython/jit/metainterp/compatible.py 
b/rpython/jit/metainterp/compatible.py
--- a/rpython/jit/metainterp/compatible.py
+++ b/rpython/jit/metainterp/compatible.py
@@ -78,6 +78,20 @@
         return True
 
     def prepare_const_arg_call(self, op, optimizer):
+        copied_op, cond = self._prepare_const_arg_call(op, optimizer)
+        if copied_op:
+            result = optimizer._can_optimize_call_pure(copied_op)
+            if result is None:
+                # just call it, we can do that with an @elidable_compatible
+                # function
+                result = do_call(
+                        optimizer.cpu, copied_op.getarglist(),
+                        copied_op.getdescr())
+            return copied_op, cond, result
+        else:
+            return None, None, None
+
+    def _prepare_const_arg_call(self, op, optimizer):
         from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
         # replace further arguments by constants, if the optimizer knows them
         # already
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py 
b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -142,17 +142,15 @@
                     ccond = info._compatibility_conditions
                     if ccond:
                         # it's subject to guard_compatible
-                        copied_op, cond = ccond.prepare_const_arg_call(
+                        copied_op, cond, result = ccond.prepare_const_arg_call(
                                 op, self.optimizer)
                         if copied_op:
-                            result = self._can_optimize_call_pure(copied_op)
-                            if result is not None:
-                                recorded = ccond.record_condition(
-                                        cond, result, self.optimizer)
-                                if recorded:
-                                    self.make_constant(op, result)
-                                    self.last_emitted_operation = REMOVED
-                                    return
+                            recorded = ccond.record_condition(
+                                    cond, result, self.optimizer)
+                            if recorded:
+                                self.make_constant(op, result)
+                                self.last_emitted_operation = REMOVED
+                                return
 
         # Step 1: check if all arguments are constant
         for arg in op.getarglist():
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
@@ -528,3 +528,78 @@
         self.check_trace_count(7)
 
 
+    def test_quasi_immutable_merge_short_preamble(self):
+        from rpython.rlib.objectmodel import we_are_translated
+        class C(object):
+            _immutable_fields_ = ['version?']
+
+        class Version(object):
+            def __init__(self, cls):
+                self.cls = cls
+        p1 = C()
+        p1.version = Version(p1)
+        p1.x = 1
+        p2 = C()
+        p2.version = Version(p2)
+        p2.x = 1
+        p3 = C()
+        p3.version = Version(p3)
+        p3.x = 3
+
+        driver = jit.JitDriver(greens = [], reds = ['n'])
+
+        class Counter(object):
+            pass
+
+        c = Counter()
+        c.count = 0
+        @jit.elidable_compatible()
+        def g(cls, v):
+            if we_are_translated():
+                c.count += 1
+            return cls.x
+
+        class B(object):
+            pass
+
+        glob_b = B()
+
+        def f(n, x):
+            glob_b.x = x
+            res = 0
+            while n > 0:
+                driver.can_enter_jit(n=n)
+                driver.jit_merge_point(n=n)
+                x = jit.hint(glob_b.x, promote_compatible=True)
+                v = x.version
+                res = g(x, v)
+                n -= res
+                if n % 11 == 5:
+                    n -= 1
+            return res
+
+        def main(x):
+            res = f(100, p1)
+            assert res == 1
+            res = f(100, p2)
+            assert res == 1
+            res = f(100, p3)
+            assert res == 3
+        main(True)
+        main(False)
+
+        x = self.meta_interp(main, [True])
+        assert x < 70
+        x = self.meta_interp(main, [True])
+        assert x < 70
+        x = self.meta_interp(main, [True])
+        assert x < 70
+        x = self.meta_interp(main, [True])
+        assert x < 70
+
+        x = self.meta_interp(main, [False])
+        assert x < 70
+        self.check_trace_count(9)
+        self.check_resops(call_i=0)
+
+
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to