[pypy-svn] r76623 - in pypy/branch/jit-bounds/pypy/jit/metainterp: . test
hakanardo at codespeak.net
hakanardo at codespeak.net
Sat Aug 14 12:13:53 CEST 2010
Author: hakanardo
Date: Sat Aug 14 12:13:51 2010
New Revision: 76623
Added:
pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_intbound.py
Modified:
pypy/branch/jit-bounds/pypy/jit/metainterp/optimizeopt.py
pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Moved bound calculations to separate class, support for lt, gt, le, ge, add, sub
Modified: pypy/branch/jit-bounds/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/branch/jit-bounds/pypy/jit/metainterp/optimizeopt.py Sat Aug 14 12:13:51 2010
@@ -17,10 +17,8 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp.history import AbstractDescr, make_hashable_int
-
-import sys
-SYSMAXINT = sys.maxint
-SYSMININT = -sys.maxint - 1
+from pypy.rlib.rarithmetic import ovfcheck
+from copy import copy
def optimize_loop_1(metainterp_sd, loop):
"""Optimize loop.operations to make it match the input of loop.specnodes
@@ -41,75 +39,43 @@
# ____________________________________________________________
-LEVEL_UNKNOWN = '\x00'
-LEVEL_NONNULL = '\x01'
-LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays
-LEVEL_CONSTANT = '\x03'
-
-
-class OptValue(object):
- _attrs_ = ('box', 'known_class', 'last_guard_index', 'level')
- last_guard_index = -1
+class IntBound(object):
+ def __init__(self, lower, upper):
+ self.has_upper = True
+ self.has_lower = True
+ self.upper = upper
+ self.lower = lower
+
+ # Returns True if the bound was updated
+ def make_le(self, other):
+ if other.has_upper:
+ if not self.has_upper or other.upper < self.upper:
+ self.has_upper = True
+ self.upper = other.upper
+ return True
+ return False
- level = LEVEL_UNKNOWN
- known_class = None
- maxint = None
- minint = None
+ def make_lt(self, other):
+ return self.make_le(other.add(-1))
- def __init__(self, box, producer=None):
- self.box = box
- self.producer = producer
- if isinstance(box, Const):
- self.level = LEVEL_CONSTANT
- # invariant: box is a Const if and only if level == LEVEL_CONSTANT
+ def make_ge(self, other):
+ if other.has_lower:
+ if not self.has_lower or other.lower > self.lower:
+ self.has_lower = True
+ self.lower = other.lower
+ return True
+ return False
- def get_maxint(self):
- if self.level == LEVEL_CONSTANT:
- return self.box.getint()
- else:
- return self.maxint
-
- def get_minint(self):
- if self.level == LEVEL_CONSTANT:
- return self.box.getint()
- else:
- return self.minint
-
- def boundint_lt(self, val):
- if val is None: return
- if self.maxint is None or val <= self.maxint:
- if val <= SYSMININT:
- self.maxint = None
- self.maxint = val - 1
-
- def boundint_le(self, val):
- if val is None: return
- if self.maxint is None or val < self.maxint:
- self.maxint = val
-
- def boundint_gt(self, val):
- if val is None: return
- if self.minint is None or val >= self.minint:
- if val >= SYSMAXINT:
- self.minint = None
- self.minint = val + 1
-
- def boundint_ge(self, val):
- if val is None: return
- if self.minint is None or val > self.minint:
- self.minint = val
+ def make_gt(self, other):
+ return self.make_ge(other.add(1))
def known_lt(self, other):
- max1 = self.get_maxint()
- min2 = other.get_minint()
- if max1 is not None and min2 is not None and max1 < min2:
+ if self.has_upper and other.has_lower and self.upper < other.lower:
return True
return False
def known_le(self, other):
- max1 = self.get_maxint()
- min2 = other.get_minint()
- if max1 is not None and min2 is not None and max1 <= min2:
+ if self.has_upper and other.has_lower and self.upper <= other.lower:
return True
return False
@@ -119,7 +85,121 @@
def known_ge(self, other):
return other.known_le(self)
+ def intersect(self, other):
+ r = False
+
+ if other.has_lower:
+ if other.lower > self.lower or not self.has_lower:
+ self.lower = other.lower
+ self.has_lower = True
+ r = True
+
+ if other.has_upper:
+ if other.upper < self.upper or not self.has_upper:
+ self.upper = other.upper
+ self.has_upper = True
+ r = True
+
+ return r
+
+ def add(self, offset):
+ res = copy(self)
+ try:
+ res.lower = ovfcheck(res.lower + offset)
+ except OverflowError:
+ res.has_lower = False
+ try:
+ res.upper = ovfcheck(res.upper + offset)
+ except OverflowError:
+ res.has_upper = False
+ return res
+
+ def add_bound(self, other):
+ res = copy(self)
+ if other.has_upper:
+ res.upper += other.upper
+ else:
+ res.has_upper = False
+ if other.has_lower:
+ res.lower += other.lower
+ else:
+ res.has_lower = False
+ return res
+
+ def sub_bound(self, other):
+ res = copy(self)
+ if other.has_upper:
+ res.lower -= other.upper
+ else:
+ res.has_lower = False
+ if other.has_lower:
+ res.upper -= other.lower
+ else:
+ res.has_upper = False
+ return res
+
+ def contains(self, val):
+ if self.has_lower and val < self.lower:
+ return False
+ if self.has_upper and val > self.upper:
+ return False
+ return True
+
+ def __repr__(self):
+ if self.has_lower:
+ l = '%4d' % self.lower
+ else:
+ l = '-Inf'
+ if self.has_upper:
+ u = '%3d' % self.upper
+ else:
+ u = 'Inf'
+ return '%s <= x <= %s' % (l, u)
+
+
+
+class IntUpperBound(IntBound):
+ def __init__(self, upper):
+ self.has_upper = True
+ self.has_lower = False
+ self.upper = upper
+ self.lower = 0
+
+class IntLowerBound(IntBound):
+ def __init__(self, lower):
+ self.has_upper = False
+ self.has_lower = True
+ self.upper = 0
+ self.lower = lower
+
+class IntUnbounded(IntBound):
+ def __init__(self):
+ self.has_upper = False
+ self.has_lower = False
+ self.upper = 0
+ self.lower = 0
+
+LEVEL_UNKNOWN = '\x00'
+LEVEL_NONNULL = '\x01'
+LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays
+LEVEL_CONSTANT = '\x03'
+
+class OptValue(object):
+ _attrs_ = ('box', 'known_class', 'last_guard_index', 'level')
+ last_guard_index = -1
+
+ level = LEVEL_UNKNOWN
+ known_class = None
+
+ def __init__(self, box, producer=None):
+ self.box = box
+ self.producer = producer
+ self.intbound = IntUnbounded()
+ if isinstance(box, Const):
+ self.make_constant(box)
+ # invariant: box is a Const if and only if level == LEVEL_CONSTANT
+
def force_box(self):
return self.box
@@ -147,6 +227,10 @@
assert isinstance(constbox, Const)
self.box = constbox
self.level = LEVEL_CONSTANT
+ try:
+ self.intbound = IntBound(self.box.getint(),self. box.getint())
+ except NotImplementedError:
+ self.intbound = IntUnbounded()
def get_constant_class(self, cpu):
level = self.level
@@ -205,10 +289,8 @@
raise NotImplementedError
class ConstantValue(OptValue):
- level = LEVEL_CONSTANT
-
def __init__(self, box):
- self.box = box
+ self.make_constant(box)
CONST_0 = ConstInt(0)
CONST_1 = ConstInt(1)
@@ -604,13 +686,10 @@
self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
def propagate_bounds_backward(self, box):
- print box
try:
op = self.producer[box]
except KeyError:
return
- print op
-
opnum = op.opnum
for value, func in propagate_bounds_ops:
if opnum == value:
@@ -1127,7 +1206,10 @@
if v2.is_constant() and v2.box.getint() == 0:
self.make_equal_to(op.result, v1)
else:
- return self.optimize_default(op)
+ self.optimize_default(op)
+ r = self.getvalue(op.result)
+ print v1.intbound.sub_bound(v2.intbound)
+ r.intbound.intersect(v1.intbound.sub_bound(v2.intbound))
def optimize_INT_ADD(self, op):
v1 = self.getvalue(op.args[0])
@@ -1139,13 +1221,15 @@
self.make_equal_to(op.result, v1)
else:
self.optimize_default(op)
+ r = self.getvalue(op.result)
+ r.intbound.intersect(v1.intbound.add_bound(v2.intbound))
def optimize_INT_LT(self, op):
v1 = self.getvalue(op.args[0])
v2 = self.getvalue(op.args[1])
- if v1.known_lt(v2):
+ if v1.intbound.known_lt(v2.intbound):
self.make_constant_int(op.result, 1)
- elif v1.known_ge(v2):
+ elif v1.intbound.known_ge(v2.intbound):
self.make_constant_int(op.result, 0)
else:
self.optimize_default(op)
@@ -1153,45 +1237,109 @@
def optimize_INT_GT(self, op):
v1 = self.getvalue(op.args[0])
v2 = self.getvalue(op.args[1])
- if v1.known_gt(v2):
+ if v1.intbound.known_gt(v2.intbound):
self.make_constant_int(op.result, 1)
- elif v1.known_le(v2):
+ elif v1.intbound.known_le(v2.intbound):
self.make_constant_int(op.result, 0)
else:
self.optimize_default(op)
- def propagate_bounds_INT_LT(self, op):
+ def optimize_INT_LE(self, op):
v1 = self.getvalue(op.args[0])
v2 = self.getvalue(op.args[1])
+ if v1.intbound.known_le(v2.intbound):
+ self.make_constant_int(op.result, 1)
+ elif v1.intbound.known_gt(v2.intbound):
+ self.make_constant_int(op.result, 0)
+ else:
+ self.optimize_default(op)
+
+ def optimize_INT_GE(self, op):
+ v1 = self.getvalue(op.args[0])
+ v2 = self.getvalue(op.args[1])
+ if v1.intbound.known_ge(v2.intbound):
+ self.make_constant_int(op.result, 1)
+ elif v1.intbound.known_lt(v2.intbound):
+ self.make_constant_int(op.result, 0)
+ else:
+ self.optimize_default(op)
+
+ def make_int_lt(self, args):
+ v1 = self.getvalue(args[0])
+ v2 = self.getvalue(args[1])
+ if v1.intbound.make_lt(v2.intbound):
+ self.propagate_bounds_backward(args[0])
+ if v2.intbound.make_gt(v1.intbound):
+ self.propagate_bounds_backward(args[1])
+
+
+ def make_int_le(self, args):
+ v1 = self.getvalue(args[0])
+ v2 = self.getvalue(args[1])
+ if v1.intbound.make_le(v2.intbound):
+ self.propagate_bounds_backward(args[0])
+ if v2.intbound.make_ge(v1.intbound):
+ self.propagate_bounds_backward(args[1])
+
+ def make_int_gt(self, args):
+ self.make_int_lt([args[1], args[0]])
+
+ def make_int_ge(self, args):
+ self.make_int_le([args[1], args[0]])
+
+ def propagate_bounds_INT_LT(self, op):
r = self.getvalue(op.result)
if r.is_constant():
if r.box.same_constant(CONST_1):
- v1.boundint_lt(v2.get_maxint())
- v2.boundint_gt(v1.get_minint())
- elif r.box.same_constant(CONST_0):
- v1.boundint_ge(v2.get_minint())
- v2.boundint_le(v1.get_maxint())
+ self.make_int_lt(op.args)
else:
- assert False, "Boolean neither True nor False"
- self.propagate_bounds_backward(op.args[0])
- self.propagate_bounds_backward(op.args[1])
+ self.make_int_ge(op.args)
def propagate_bounds_INT_GT(self, op):
- v1 = self.getvalue(op.args[0])
- v2 = self.getvalue(op.args[1])
r = self.getvalue(op.result)
if r.is_constant():
if r.box.same_constant(CONST_1):
- v2.boundint_lt(v1.get_maxint())
- v1.boundint_gt(v2.get_minint())
- elif r.box.same_constant(CONST_0):
- v2.boundint_ge(v1.get_minint())
- v1.boundint_le(v2.get_maxint())
+ self.make_int_gt(op.args)
+ else:
+ self.make_int_le(op.args)
+
+ def propagate_bounds_INT_LE(self, op):
+ r = self.getvalue(op.result)
+ if r.is_constant():
+ if r.box.same_constant(CONST_1):
+ self.make_int_le(op.args)
else:
- assert False, "Boolean neither True nor False"
- self.propagate_bounds_backward(op.args[0])
+ self.make_int_gt(op.args)
+
+ def propagate_bounds_INT_GE(self, op):
+ r = self.getvalue(op.result)
+ if r.is_constant():
+ if r.box.same_constant(CONST_1):
+ self.make_int_ge(op.args)
+ else:
+ self.make_int_lt(op.args)
+
+ def propagate_bounds_INT_ADD(self, op):
+ v1 = self.getvalue(op.args[0])
+ v2 = self.getvalue(op.args[1])
+ r = self.getvalue(op.result)
+ b = r.intbound.sub_bound(v2.intbound)
+ if v1.intbound.intersect(b):
+ self.propagate_bounds_backward(op.args[0])
+ b = r.intbound.sub_bound(v1.intbound)
+ if v2.intbound.intersect(b):
self.propagate_bounds_backward(op.args[1])
+ def propagate_bounds_INT_SUB(self, op):
+ v1 = self.getvalue(op.args[0])
+ v2 = self.getvalue(op.args[1])
+ r = self.getvalue(op.result)
+ b = r.intbound.add_bound(v2.intbound)
+ if v1.intbound.intersect(b):
+ self.propagate_bounds_backward(op.args[0])
+ # FIXME:
+ # b = r.intbound.sub_bound(v1.intbound).mul(-1)
+ # if v2.intbound.intersect(b):
optimize_ops = _findall(Optimizer, 'optimize_')
propagate_bounds_ops = _findall(Optimizer, 'propagate_bounds_')
Added: pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_intbound.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_intbound.py Sat Aug 14 12:13:51 2010
@@ -0,0 +1,199 @@
+from pypy.jit.metainterp.optimizeopt import IntBound, IntUpperBound, \
+ IntLowerBound, IntUnbounded
+from copy import copy
+
+def bound(a,b):
+ if a is None and b is None:
+ return IntUnbounded()
+ elif a is None:
+ return IntUpperBound(b)
+ elif b is None:
+ return IntLowerBound(a)
+ else:
+ return IntBound(a,b)
+
+def const(a):
+ return bound(a,a)
+
+def some_bounds():
+ brd = [None] + range(-2, 3)
+ for lower in brd:
+ for upper in brd:
+ if lower is not None and upper is not None and lower > upper:
+ continue
+ yield (lower, upper, bound(lower, upper))
+
+nbr = range(-5, 6)
+
+def test_known():
+ for lower, upper, b in some_bounds():
+ inside = []
+ border = []
+ for n in nbr:
+ if (lower is None or n >= lower) and \
+ (upper is None or n <= upper):
+ if n == lower or n ==upper:
+ border.append(n)
+ else:
+ inside.append(n)
+
+ for n in nbr:
+ c = const(n)
+ if n in inside:
+ assert b.contains(n)
+ assert not b.known_lt(c)
+ assert not b.known_gt(c)
+ assert not b.known_le(c)
+ assert not b.known_ge(c)
+ elif n in border:
+ assert b.contains(n)
+ if n == upper:
+ assert b.known_le(const(upper))
+ else:
+ assert b.known_ge(const(lower))
+ else:
+ assert not b.contains(n)
+ some = (border + inside)[0]
+ if n < some:
+ assert b.known_gt(c)
+ else:
+ assert b.known_lt(c)
+
+
+def test_make():
+ for _, _, b1 in some_bounds():
+ for _, _, b2 in some_bounds():
+ lt = IntUnbounded()
+ lt.make_lt(b1)
+ lt.make_lt(b2)
+ for n in nbr:
+ c = const(n)
+ if b1.known_le(c) or b2.known_le(c):
+ assert lt.known_lt(c)
+ else:
+ assert not lt.known_lt(c)
+ assert not lt.known_gt(c)
+ assert not lt.known_ge(c)
+
+ gt = IntUnbounded()
+ gt.make_gt(b1)
+ gt.make_gt(b2)
+ for n in nbr:
+ c = const(n)
+ if b1.known_ge(c) or b2.known_ge(c):
+ assert gt.known_gt(c)
+ else:
+ assert not gt.known_gt(c)
+ assert not gt.known_lt(c)
+ assert not gt.known_le(c)
+
+ le = IntUnbounded()
+ le.make_le(b1)
+ le.make_le(b2)
+ for n in nbr:
+ c = const(n)
+ if b1.known_le(c) or b2.known_le(c):
+ assert le.known_le(c)
+ else:
+ assert not le.known_le(c)
+ assert not le.known_gt(c)
+ assert not le.known_ge(c)
+
+
+ ge = IntUnbounded()
+ ge.make_ge(b1)
+ ge.make_ge(b2)
+ for n in nbr:
+ c = const(n)
+ if b1.known_ge(c) or b2.known_ge(c):
+ assert ge.known_ge(c)
+ else:
+ assert not ge.known_ge(c)
+ assert not ge.known_lt(c)
+ assert not ge.known_le(c)
+
+ gl = IntUnbounded()
+ gl.make_ge(b1)
+ gl.make_le(b2)
+ for n in nbr:
+ c = const(n)
+ if b1.known_ge(c):
+ assert gl.known_ge(c)
+ else:
+ assert not gl.known_ge(c)
+ assert not gl.known_gt(c)
+ if b2.known_le(c):
+ assert gl.known_le(c)
+ else:
+ assert not gl.known_le(c)
+ assert not gl.known_lt(c)
+
+def test_intersect():
+ for _, _, b1 in some_bounds():
+ for _, _, b2 in some_bounds():
+ b = copy(b1)
+ b.intersect(b2)
+ for n in nbr:
+ if b1.contains(n) and b2.contains(n):
+ assert b.contains(n)
+ else:
+ assert not b.contains(n)
+
+def test_add():
+ for _, _, b1 in some_bounds():
+ for n1 in nbr:
+ b2 = b1.add(n1)
+ for n2 in nbr:
+ c1 = const(n2)
+ c2 = const(n2 + n1)
+
+ if b1.known_le(c1):
+ assert b2.known_le(c2)
+ else:
+ assert not b2.known_le(c2)
+
+ if b1.known_ge(c1):
+ assert b2.known_ge(c2)
+ else:
+ assert not b2.known_ge(c2)
+
+ if b1.known_le(c1):
+ assert b2.known_le(c2)
+ else:
+ assert not b2.known_lt(c2)
+
+ if b1.known_lt(c1):
+ assert b2.known_lt(c2)
+ else:
+ assert not b2.known_lt(c2)
+
+ if b1.known_gt(c1):
+ assert b2.known_gt(c2)
+ else:
+ assert not b2.known_gt(c2)
+
+def test_add_bound():
+ for _, _, b1 in some_bounds():
+ for _, _, b2 in some_bounds():
+ b3 = b1.add_bound(b2)
+ for n1 in nbr:
+ for n2 in nbr:
+ if b1.contains(n1) and b2.contains(n2):
+ assert b3.contains(n1 + n2)
+
+ a=bound(2, 4).add_bound(bound(1, 2))
+ assert not a.contains(2)
+ assert not a.contains(7)
+
+def test_sub_bound():
+ for _, _, b1 in some_bounds():
+ for _, _, b2 in some_bounds():
+ b3 = b1.sub_bound(b2)
+ for n1 in nbr:
+ for n2 in nbr:
+ if b1.contains(n1) and b2.contains(n2):
+ assert b3.contains(n1 - n2)
+
+ a=bound(2, 4).sub_bound(bound(1, 2))
+ assert not a.contains(-1)
+ assert not a.contains(4)
Modified: pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/jit-bounds/pypy/jit/metainterp/test/test_optimizeopt.py Sat Aug 14 12:13:51 2010
@@ -3112,6 +3112,135 @@
"""
self.optimize_loop(ops, 'Not', expected)
+ def test_bound_lt_tripple(self):
+ ops = """
+ [i0]
+ i1 = int_lt(i0, 0)
+ guard_true(i1) []
+ i2 = int_lt(i0, 7)
+ guard_true(i2) []
+ i3 = int_lt(i0, 5)
+ guard_true(i3) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_lt(i0, 0)
+ guard_true(i1) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_lt_add(self):
+ ops = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ i2 = int_add(i0, 10)
+ i3 = int_lt(i2, 15)
+ guard_true(i3) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ i2 = int_add(i0, 10)
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_lt_add_before(self):
+ ops = """
+ [i0]
+ i2 = int_add(i0, 10)
+ i3 = int_lt(i2, 15)
+ guard_true(i3) []
+ i1 = int_lt(i0, 6)
+ guard_true(i1) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i2 = int_add(i0, 10)
+ i3 = int_lt(i2, 15)
+ guard_true(i3) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_lt_sub(self):
+ ops = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ i2 = int_sub(i0, 10)
+ i3 = int_lt(i2, -5)
+ guard_true(i3) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ i2 = int_sub(i0, 10)
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_lt_sub_before(self):
+ ops = """
+ [i0]
+ i2 = int_sub(i0, 10)
+ i3 = int_lt(i2, -5)
+ guard_true(i3) []
+ i1 = int_lt(i0, 5)
+ guard_true(i1) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i2 = int_sub(i0, 10)
+ i3 = int_lt(i2, -5)
+ guard_true(i3) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_ltle(self):
+ ops = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ i2 = int_le(i0, 3)
+ guard_true(i2) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_lt(i0, 4)
+ guard_true(i1) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
+ def test_bound_lelt(self):
+ ops = """
+ [i0]
+ i1 = int_le(i0, 4)
+ guard_true(i1) []
+ i2 = int_lt(i0, 5)
+ guard_true(i2) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_le(i0, 4)
+ guard_true(i1) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
def test_bound_gt(self):
ops = """
[i0]
@@ -3129,27 +3258,40 @@
"""
self.optimize_loop(ops, 'Not', expected)
- def test_bound_lt_tripple(self):
+ def test_bound_gtge(self):
ops = """
[i0]
- i1 = int_lt(i0, 0)
+ i1 = int_gt(i0, 5)
guard_true(i1) []
- i2 = int_lt(i0, 7)
+ i2 = int_ge(i0, 6)
guard_true(i2) []
- i3 = int_lt(i0, 5)
- guard_true(i3) []
jump(i0)
"""
expected = """
[i0]
- i1 = int_lt(i0, 0)
+ i1 = int_gt(i0, 5)
guard_true(i1) []
jump(i0)
"""
self.optimize_loop(ops, 'Not', expected)
-
-
+ def test_bound_gegt(self):
+ ops = """
+ [i0]
+ i1 = int_ge(i0, 5)
+ guard_true(i1) []
+ i2 = int_gt(i0, 4)
+ guard_true(i2) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_ge(i0, 5)
+ guard_true(i1) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
##class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin):
More information about the Pypy-commit
mailing list