Author: Carl Friedrich Bolz <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit