[pypy-svn] pypy jit-unroll-loops: Allow integer divisions to be optimized somewhat if the arguments are known to be possitive. The last 3 ops after int_floordiv should be removed by the backend since their results are never used, right? Where does the "(i8 & i6) == -1" opps come from?
hakanardo
commits-noreply at bitbucket.org
Tue Jan 4 20:02:05 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-unroll-loops
Changeset: r40395:7269121d3536
Date: 2011-01-04 20:01 +0100
http://bitbucket.org/pypy/pypy/changeset/7269121d3536/
Log: Allow integer divisions to be optimized somewhat if the arguments
are known to be possitive. The last 3 ops after int_floordiv should
be removed by the backend since their results are never used, right?
Where does the "(i8 & i6) == -1" opps come from?
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -3868,6 +3868,136 @@
"""
self.optimize_loop(ops, expected)
+ def test_bound_xor(self):
+ ops = """
+ [i0, i1, i2]
+ it1 = int_ge(i1, 0)
+ guard_true(it1) []
+ it2 = int_gt(i2, 0)
+ guard_true(it2) []
+ ix1 = int_xor(i0, i0)
+ ix1t = int_ge(ix1, 0)
+ guard_true(ix1t) []
+ ix2 = int_xor(i0, i1)
+ ix2t = int_ge(ix2, 0)
+ guard_true(ix2t) []
+ ix3 = int_xor(i1, i0)
+ ix3t = int_ge(ix3, 0)
+ guard_true(ix3t) []
+ ix4 = int_xor(i1, i2)
+ ix4t = int_ge(ix4, 0)
+ guard_true(ix4t) []
+ jump(i0, i1, i2)
+ """
+ preamble = """
+ [i0, i1, i2]
+ it1 = int_ge(i1, 0)
+ guard_true(it1) []
+ it2 = int_gt(i2, 0)
+ guard_true(it2) []
+ ix2 = int_xor(i0, i1)
+ ix2t = int_ge(ix2, 0)
+ guard_true(ix2t) []
+ ix3 = int_xor(i1, i0)
+ ix3t = int_ge(ix3, 0)
+ guard_true(ix3t) []
+ ix4 = int_xor(i1, i2)
+ jump(i0, i1, i2)
+ """
+ expected = """
+ [i0, i1, i2]
+ jump(i0, i1, i2)
+ """
+ self.optimize_loop(ops, expected, preamble)
+
+ def test_bound_int_is_zero(self):
+ ops = """
+ [i1, i2a, i2b, i2c]
+ i3 = int_is_zero(i1)
+ i4 = int_gt(i2a, 7)
+ guard_true(i4) []
+ i5 = int_is_zero(i2a)
+ guard_false(i5) []
+ i6 = int_le(i2b, -7)
+ guard_true(i6) []
+ i7 = int_is_zero(i2b)
+ guard_false(i7) []
+ i8 = int_gt(i2c, -7)
+ guard_true(i8) []
+ i9 = int_is_zero(i2c)
+ jump(i1, i2a, i2b, i2c)
+ """
+ preamble = """
+ [i1, i2a, i2b, i2c]
+ i3 = int_is_zero(i1)
+ i4 = int_gt(i2a, 7)
+ guard_true(i4) []
+ i6 = int_le(i2b, -7)
+ guard_true(i6) []
+ i8 = int_gt(i2c, -7)
+ guard_true(i8) []
+ i9 = int_is_zero(i2c)
+ jump(i1, i2a, i2b, i2c)
+ """
+ expected = """
+ [i0, i1, i2, i3]
+ jump(i0, i1, i2, i3)
+ """
+ self.optimize_loop(ops, expected, preamble)
+
+ def test_division(self):
+ ops = """
+ [i7, i6, i8]
+ it1 = int_gt(i7, 0)
+ guard_true(it1) []
+ it2 = int_gt(i6, 0)
+ guard_true(it2) []
+ i13 = int_is_zero(i6)
+ guard_false(i13) []
+ i15 = int_and(i8, i6)
+ i17 = int_eq(i15, -1)
+ guard_false(i17) []
+ i18 = int_floordiv(i7, i6)
+ i19 = int_xor(i7, i6)
+ i21 = int_lt(i19, 0)
+ i22 = int_mod(i7, i6)
+ i23 = int_is_true(i22)
+ i24 = int_and(i21, i23)
+ i25 = int_sub(i18, i24)
+ jump(i7, i25, i8)
+ """
+ preamble = """
+ [i7, i6, i8]
+ it1 = int_gt(i7, 0)
+ guard_true(it1) []
+ it2 = int_gt(i6, 0)
+ guard_true(it2) []
+ i15 = int_and(i8, i6)
+ i17 = int_eq(i15, -1)
+ guard_false(i17) []
+ i18 = int_floordiv(i7, i6)
+ i19 = int_xor(i7, i6)
+ i22 = int_mod(i7, i6)
+ i23 = int_is_true(i22)
+ jump(i7, i18, i8)
+ """
+ expected = """
+ [i7, i6, i8]
+ it2 = int_gt(i6, 0)
+ guard_true(it2) []
+ i15 = int_and(i8, i6)
+ i17 = int_eq(i15, -1)
+ guard_false(i17) []
+ i18 = int_floordiv(i7, i6)
+ i19 = int_xor(i7, i6)
+ i22 = int_mod(i7, i6)
+ i23 = int_is_true(i22)
+ jump(i7, i18, i8)
+ """
+ self.optimize_loop(ops, expected, preamble)
+
+
+
def test_subsub_ovf(self):
ops = """
[i0]
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -62,6 +62,18 @@
optimize_GUARD_FALSE = optimize_GUARD_TRUE
optimize_GUARD_VALUE = optimize_GUARD_TRUE
+ def optimize_INT_XOR(self, op):
+ v1 = self.getvalue(op.getarg(0))
+ v2 = self.getvalue(op.getarg(1))
+ if v1 is v2:
+ self.make_constant_int(op.result, 0)
+ return
+ self.emit_operation(op)
+ if v1.intbound.known_ge(IntBound(0, 0)) and \
+ v2.intbound.known_ge(IntBound(0, 0)):
+ r = self.getvalue(op.result)
+ r.intbound.make_ge(IntLowerBound(0))
+
def optimize_INT_AND(self, op):
v1 = self.getvalue(op.getarg(0))
v2 = self.getvalue(op.getarg(1))
diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -222,7 +222,7 @@
# return (x/y) - (((x^y)<0)&((x%y)!=0));
v_xor = hop.genop(prefix + 'xor', vlist,
resulttype=repr)
- v_xor_le = hop.genop(prefix + 'le', [v_xor, c_zero],
+ v_xor_le = hop.genop(prefix + 'lt', [v_xor, c_zero],
resulttype=Bool)
v_xor_le = hop.llops.convertvar(v_xor_le, bool_repr, repr)
v_mod = hop.genop(prefix + 'mod', vlist,
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -120,6 +120,9 @@
box = self.box
assert isinstance(box, Const)
return box.nonnull()
+ elif self.intbound.known_gt(IntBound(0, 0)) or \
+ self.intbound.known_lt(IntBound(0, 0)):
+ return True
else:
return False
diff --git a/pypy/module/pypyjit/test/test_pypy_c.py b/pypy/module/pypyjit/test/test_pypy_c.py
--- a/pypy/module/pypyjit/test/test_pypy_c.py
+++ b/pypy/module/pypyjit/test/test_pypy_c.py
@@ -1320,7 +1320,33 @@
assert call.getarg(1).value == 2.0
assert call.getarg(2).value == 3.0
- # test_circular
+ def test_xor(self):
+ values = (-4, -3, -2, -1, 0, 1, 2, 3, 4)
+ for a in values:
+ for b in values:
+ if a^b >= 0:
+ r = 2000
+ else:
+ r = 0
+ if a > 0 and b > 1:
+ ops = 0
+ else:
+ ops = 0
+
+ self.run_source('''
+ def main(a, b):
+ i = sa = 0
+ while i < 2000:
+ if a > 0: # Specialises the loop
+ pass
+ if b > 1:
+ pass
+ if a^b >= 0:
+ sa += 1
+ i += 1
+ return sa
+ ''', ops, ([a, b], r))
+
class AppTestJIT(PyPyCJITTests):
def setup_class(cls):
More information about the Pypy-commit
mailing list