[pypy-svn] r77545 - in pypy/branch/jit-unroll-loops/pypy/jit/metainterp: optimizeopt test
hakanardo at codespeak.net
hakanardo at codespeak.net
Sat Oct 2 10:31:31 CEST 2010
Author: hakanardo
Date: Sat Oct 2 10:31:29 2010
New Revision: 77545
Modified:
pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py
pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py
Log:
Look ahead on future operations using optimizer.operations no longer suported. test_loop_invariant_mul_ovf passing.
Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py (original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/intbounds.py Sat Oct 2 10:31:29 2010
@@ -9,14 +9,28 @@
"""Keeps track of the bounds placed on integers by the guards and
remove redundant guards"""
+ def setup(self, virtuals):
+ self.posponedop = None
+ self.nextop = None
+
def propagate_forward(self, op):
+ if op.is_ovf():
+ self.posponedop = op
+ return
+ if self.posponedop:
+ self.nextop = op
+ op = self.posponedop
+ self.posponedop = None
+
opnum = op.getopnum()
for value, func in optimize_ops:
if opnum == value:
func(self, op)
break
else:
+ assert not op.is_ovf()
self.emit_operation(op)
+
def propagate_bounds_backward(self, box):
# FIXME: This takes care of the instruction where box is the reuslt
@@ -85,45 +99,45 @@
v2 = self.getvalue(op.getarg(1))
resbound = v1.intbound.add_bound(v2.intbound)
if resbound.has_lower and resbound.has_upper and \
- self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+ self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
# Transform into INT_ADD and remove guard
op = op.copy_and_change(rop.INT_ADD)
- self.skip_nextop()
self.optimize_INT_ADD(op) # emit the op
else:
self.emit_operation(op)
r = self.getvalue(op.result)
r.intbound.intersect(resbound)
+ self.emit_operation(self.nextop)
def optimize_INT_SUB_OVF(self, op):
v1 = self.getvalue(op.getarg(0))
v2 = self.getvalue(op.getarg(1))
resbound = v1.intbound.sub_bound(v2.intbound)
if resbound.has_lower and resbound.has_upper and \
- self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+ self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
# Transform into INT_SUB and remove guard
op = op.copy_and_change(rop.INT_SUB)
- self.skip_nextop()
self.optimize_INT_SUB(op) # emit the op
else:
self.emit_operation(op)
r = self.getvalue(op.result)
r.intbound.intersect(resbound)
-
+ self.emit_operation(self.nextop)
+
def optimize_INT_MUL_OVF(self, op):
v1 = self.getvalue(op.getarg(0))
v2 = self.getvalue(op.getarg(1))
resbound = v1.intbound.mul_bound(v2.intbound)
if resbound.has_lower and resbound.has_upper and \
- self.nextop().getopnum() == rop.GUARD_NO_OVERFLOW:
+ self.nextop.getopnum() == rop.GUARD_NO_OVERFLOW:
# Transform into INT_MUL and remove guard
op = op.copy_and_change(rop.INT_MUL)
- self.skip_nextop()
self.optimize_INT_MUL(op) # emit the op
else:
self.emit_operation(op)
r = self.getvalue(op.result)
r.intbound.intersect(resbound)
+ self.emit_operation(self.nextop)
def optimize_INT_LT(self, op):
v1 = self.getvalue(op.getarg(0))
Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py (original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py Sat Oct 2 10:31:29 2010
@@ -182,12 +182,6 @@
op = ResOperation(opnum, args, result)
self.optimizer.pure_operations[self.optimizer.make_args_key(op)] = op
- def nextop(self):
- return self.optimizer.loop.operations[self.optimizer.i + 1]
-
- def skip_nextop(self):
- self.optimizer.i += 1
-
def setup(self, virtuals):
pass
@@ -205,6 +199,7 @@
self.pure_operations = args_dict()
self.producer = {}
self.pendingfields = []
+ self.posponedop = None
if optimizations:
self.first_optimization = optimizations[0]
@@ -254,9 +249,9 @@
return constbox
return None
- def make_equal_to(self, box, value):
+ def make_equal_to(self, box, value, replace=False):
assert isinstance(value, OptValue)
- assert box not in self.values
+ assert replace or box not in self.values
self.values[box] = value
def make_constant(self, box, constbox):
@@ -392,10 +387,17 @@
def optimize_default(self, op):
canfold = op.is_always_pure()
- is_ovf = op.is_ovf()
- if is_ovf:
- nextop = self.loop.operations[self.i + 1]
+ if op.is_ovf():
+ self.posponedop = op
+ return
+ if self.posponedop:
+ nextop = op
+ op = self.posponedop
+ self.posponedop = None
canfold = nextop.getopnum() == rop.GUARD_NO_OVERFLOW
+ else:
+ nextop = None
+
if canfold:
for i in range(op.numargs()):
if self.get_constant_box(op.getarg(i)) is None:
@@ -406,9 +408,8 @@
for i in range(op.numargs())]
resbox = execute_nonspec(self.cpu, None,
op.getopnum(), argboxes, op.getdescr())
+ # FIXME: Don't we need to check for an overflow here?
self.make_constant(op.result, resbox.constbox())
- if is_ovf:
- self.i += 1 # skip next operation, it is the unneeded guard
return
# did we do the exact same operation already?
@@ -416,20 +417,22 @@
oldop = self.pure_operations.get(args, None)
if oldop is not None and oldop.getdescr() is op.getdescr():
assert oldop.getopnum() == op.getopnum()
- self.make_equal_to(op.result, self.getvalue(oldop.result))
- if is_ovf:
- self.i += 1 # skip next operation, it is the unneeded guard
+ self.make_equal_to(op.result, self.getvalue(oldop.result),
+ True)
return
else:
self.pure_operations[args] = op
# otherwise, the operation remains
self.emit_operation(op)
+ if nextop:
+ self.emit_operation(nextop)
- def optimize_GUARD_NO_OVERFLOW(self, op):
- # otherwise the default optimizer will clear fields, which is unwanted
- # in this case
- self.emit_operation(op)
+ #def optimize_GUARD_NO_OVERFLOW(self, op):
+ # # otherwise the default optimizer will clear fields, which is unwanted
+ # # in this case
+ # self.emit_operation(op)
+ # FIXME: Is this still needed?
def optimize_DEBUG_MERGE_POINT(self, op):
self.emit_operation(op)
Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/test/test_basic.py Sat Oct 2 10:31:29 2010
@@ -334,11 +334,11 @@
return res
res = self.meta_interp(f, [6, 7])
assert res == 308
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1, 'guard_no_overflow': 1,
- 'int_add': 2, 'int_sub': 1, 'int_gt': 1,
- 'int_mul': 1, 'int_mul_ovf': 1,
- 'jump': 1})
+ self.check_loop_count(2)
+ self.check_loops({'guard_true': 2, 'guard_no_overflow': 1,
+ 'int_add': 4, 'int_sub': 2, 'int_gt': 2,
+ 'int_mul': 2, 'int_mul_ovf': 1,
+ 'jump': 2})
def test_loop_invariant_mul_bridge1(self):
myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -364,12 +364,12 @@
myjitdriver.can_enter_jit(x=x, y=y, res=res)
myjitdriver.jit_merge_point(x=x, y=y, res=res)
res += x * x
- if y<8:
+ if y<16:
res += 1
y -= 1
return res
- res = self.meta_interp(f, [6, 16])
- assert res == 583
+ res = self.meta_interp(f, [6, 32])
+ assert res == 1167
self.check_loop_count(3)
self.check_loops({'int_lt': 1, 'int_gt': 1,
'guard_false': 1, 'guard_true': 1,
More information about the Pypy-commit
mailing list