Author: Carl Friedrich Bolz <[email protected]>
Branch: guard-compatible
Changeset: r85357:625f490451ee
Date: 2016-06-22 17:14 +0200
http://bitbucket.org/pypy/pypy/changeset/625f490451ee/
Log: start doing loop-invariant code motion of guard_compatible
(something is currently very broken, but wanted to commit an
intermediate step)
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
@@ -33,15 +33,26 @@
self.last_quasi_immut_field_op = None
# -1 means "stay on the original trace"
self.jump_target = -1
+ self.frozen = False
+
+ def frozen_copy(self):
+ res = CompatibilityCondition(self.known_valid)
+ res.conditions = self.conditions[:]
+ assert self.jump_target == -1
+ res.frozen = True
+ return res
def record_condition(self, cond, res, optimizer):
for oldcond in self.conditions:
if oldcond.same_cond(cond, res):
- return
+ return True
+ if self.frozen:
+ False
cond.activate(res, optimizer)
if self.conditions and self.conditions[-1].debug_mp_str ==
cond.debug_mp_str:
cond.debug_mp_str = ''
self.conditions.append(cond)
+ return True
def register_quasi_immut_field(self, op):
self.last_quasi_immut_field_op = op
diff --git a/rpython/jit/metainterp/optimizeopt/info.py
b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -121,8 +121,8 @@
assert self.get_last_guard(optimizer).is_guard()
def make_guards(self, op, short, optimizer):
- op = ResOperation(rop.GUARD_NONNULL, [op])
- short.append(op)
+ guard_op = ResOperation(rop.GUARD_NONNULL, [op])
+ short.append(guard_op)
return PtrInfo.make_guards(self, op, short, optimizer)
class AbstractVirtualPtrInfo(NonNullPtrInfo):
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
@@ -147,10 +147,12 @@
if copied_op:
result = self._can_optimize_call_pure(copied_op)
if result is not None:
- self.make_constant(op, result)
- self.last_emitted_operation = REMOVED
- ccond.record_condition(cond, result,
self.optimizer)
- 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/optimizeopt/test/test_compatible.py
b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
@@ -302,3 +302,80 @@
"""
self.optimize_loop(ops, expected, expected_preamble=preamble)
+
+ def test_guard_compatible_call_pure(self):
+ call_pure_results = {
+ (ConstInt(123), ConstPtr(self.myptr)): ConstInt(5),
+ (ConstInt(124), ConstPtr(self.myptr)): ConstInt(7),
+ }
+ ops = """
+ [p1]
+ guard_compatible(p1, ConstPtr(myptr)) []
+ i3 = call_pure_i(123, p1, descr=plaincalldescr)
+ escape_n(i3)
+ guard_compatible(p1, ConstPtr(myptr)) []
+ i5 = call_pure_i(124, p1, descr=plaincalldescr)
+ escape_n(i5)
+ jump(p1)
+ """
+ preamble = """
+ [p1]
+ guard_compatible(p1, ConstPtr(myptr)) []
+ escape_n(5)
+ escape_n(7)
+ jump(p1)
+ """
+ expected = """
+ [p0]
+ escape_n(5)
+ escape_n(7)
+ jump(p0)
+ """
+ self.optimize_loop(ops, expected, expected_preamble=preamble,
call_pure_results=call_pure_results)
+ # whitebox-test the guard_compatible descr a bit
+ descr = self.preamble.operations[1].getdescr()
+ assert descr._compatibility_conditions is not None
+ assert
descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.myptr))
+ assert len(descr._compatibility_conditions.conditions) == 2
+
+ def test_quasiimmut(self):
+ ops = """
+ [p1]
+ guard_compatible(p1, ConstPtr(quasiptr)) []
+ quasiimmut_field(p1, descr=quasiimmutdescr)
+ guard_not_invalidated() []
+ i0 = getfield_gc_i(p1, descr=quasifielddescr)
+ i1 = call_pure_i(123, p1, i0, descr=nonwritedescr)
+ quasiimmut_field(p1, descr=quasiimmutdescr)
+ guard_not_invalidated() []
+ i3 = getfield_gc_i(p1, descr=quasifielddescr)
+ i4 = call_pure_i(123, p1, i3, descr=nonwritedescr)
+ escape_n(i1)
+ escape_n(i4)
+ jump(p1)
+ """
+ preamble = """
+ [p1]
+ guard_compatible(p1, ConstPtr(quasiptr)) []
+ guard_not_invalidated() []
+ i0 = getfield_gc_i(p1, descr=quasifielddescr) # will be removed by the
backend
+ escape_n(5)
+ escape_n(5)
+ jump(p1)
+ """
+ expected = """
+ [p1]
+ guard_not_invalidated() []
+ escape_n(5)
+ escape_n(5)
+ jump(p1)
+ """
+
+ call_pure_results = {
+ (ConstInt(123), ConstPtr(self.quasiptr), ConstInt(-4247)):
ConstInt(5),
+ }
+ self.optimize_loop(ops, expected, expected_preamble=preamble,
call_pure_results=call_pure_results)
+ descr = self.preamble.operations[1].getdescr()
+ assert descr._compatibility_conditions is not None
+ assert
descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.quasiptr))
+ assert len(descr._compatibility_conditions.conditions) == 1
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -60,6 +60,7 @@
info = self.unroll_and_optimize(loop, call_pure_results, jump_values)
preamble = info.preamble
+ self.preamble = preamble
preamble.check_consistency(check_descr=False)
#
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
@@ -88,7 +88,9 @@
if preamble_info._compatibility_conditions:
info_in_loop = op.get_forwarded()
if info_in_loop is not None:
- info_in_loop._compatibility_conditions =
preamble_info._compatibility_conditions
+ ccond = preamble_info._compatibility_conditions
+ ccond = ccond.frozen_copy()
+ info_in_loop._compatibility_conditions = ccond
elif isinstance(preamble_info, intutils.IntBound):
if preamble_info.lower > MININT/2 or preamble_info.upper <
MAXINT/2:
intbound = self.getintbound(op)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit