[pypy-svn] r76655 - in pypy/trunk/pypy/jit/metainterp: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Tue Aug 17 16:57:52 CEST 2010
Author: cfbolz
Date: Tue Aug 17 16:57:51 2010
New Revision: 76655
Modified:
pypy/trunk/pypy/jit/metainterp/executor.py
pypy/trunk/pypy/jit/metainterp/optimizeopt.py
pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
(cfbolz, arigo checking): constant-fold ovf operations
Modified: pypy/trunk/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/executor.py (original)
+++ pypy/trunk/pypy/jit/metainterp/executor.py Tue Aug 17 16:57:51 2010
@@ -172,34 +172,36 @@
[x1box.getref_base(), x2box.getref_base()], None)
def do_int_add_ovf(cpu, metainterp, box1, box2):
- assert metainterp is not None
+ # the overflow operations can be called without a metainterp, if an
+ # overflow cannot occur
a = box1.getint()
b = box2.getint()
try:
z = ovfcheck(a + b)
except OverflowError:
+ assert metainterp is not None
metainterp.execute_raised(OverflowError(), constant=True)
z = 0
return BoxInt(z)
def do_int_sub_ovf(cpu, metainterp, box1, box2):
- assert metainterp is not None
a = box1.getint()
b = box2.getint()
try:
z = ovfcheck(a - b)
except OverflowError:
+ assert metainterp is not None
metainterp.execute_raised(OverflowError(), constant=True)
z = 0
return BoxInt(z)
def do_int_mul_ovf(cpu, metainterp, box1, box2):
- assert metainterp is not None
a = box1.getint()
b = box2.getint()
try:
z = ovfcheck(a * b)
except OverflowError:
+ assert metainterp is not None
metainterp.execute_raised(OverflowError(), constant=True)
z = 0
return BoxInt(z)
Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Tue Aug 17 16:57:51 2010
@@ -526,7 +526,9 @@
def propagate_forward(self):
self.exception_might_have_happened = False
self.newoperations = []
- for op in self.loop.operations:
+ self.i = 0
+ while self.i < len(self.loop.operations):
+ op = self.loop.operations[self.i]
opnum = op.opnum
for value, func in optimize_ops:
if opnum == value:
@@ -534,6 +536,7 @@
break
else:
self.optimize_default(op)
+ self.i += 1
self.loop.operations = self.newoperations
# accumulate counters
self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
@@ -588,7 +591,12 @@
descr.make_a_counter_per_value(op)
def optimize_default(self, op):
- if op.is_always_pure():
+ canfold = op.is_always_pure()
+ is_ovf = op.is_ovf()
+ if is_ovf:
+ nextop = self.loop.operations[self.i + 1]
+ canfold = nextop.opnum == rop.GUARD_NO_OVERFLOW
+ if canfold:
for arg in op.args:
if self.get_constant_box(arg) is None:
break
@@ -598,6 +606,8 @@
resbox = execute_nonspec(self.cpu, None,
op.opnum, argboxes, op.descr)
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?
@@ -611,6 +621,8 @@
if oldop is not None and oldop.descr is op.descr:
assert oldop.opnum == op.opnum
self.make_equal_to(op.result, self.getvalue(oldop.result))
+ if is_ovf:
+ self.i += 1 # skip next operation, it is the unneeded guard
return
elif self.find_rewritable_bool(op, args):
return
Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Tue Aug 17 16:57:51 2010
@@ -285,6 +285,24 @@
"""
self.optimize_loop(ops, '', expected)
+ def test_constant_propagate_ovf(self):
+ ops = """
+ []
+ i0 = int_add_ovf(2, 3)
+ guard_no_overflow() []
+ i1 = int_is_true(i0)
+ guard_true(i1) []
+ i2 = int_is_zero(i1)
+ guard_false(i2) []
+ guard_value(i0, 5) []
+ jump()
+ """
+ expected = """
+ []
+ jump()
+ """
+ self.optimize_loop(ops, '', expected)
+
def test_constfold_all(self):
from pypy.jit.backend.llgraph.llimpl import TYPES # xxx fish
from pypy.jit.metainterp.executor import execute_nonspec
@@ -2098,6 +2116,33 @@
"""
self.optimize_loop(ops, 'Not', expected)
+ def test_remove_duplicate_pure_op_ovf(self):
+ ops = """
+ [i1]
+ i3 = int_add_ovf(i1, 1)
+ guard_no_overflow() []
+ i3b = int_is_true(i3)
+ guard_true(i3b) []
+ i4 = int_add_ovf(i1, 1)
+ guard_no_overflow() []
+ i4b = int_is_true(i4)
+ guard_true(i4b) []
+ escape(i3)
+ escape(i4)
+ jump(i1)
+ """
+ expected = """
+ [i1]
+ i3 = int_add_ovf(i1, 1)
+ guard_no_overflow() []
+ i3b = int_is_true(i3)
+ guard_true(i3b) []
+ escape(i3)
+ escape(i3)
+ jump(i1)
+ """
+ self.optimize_loop(ops, "Not", expected)
+
def test_int_and_or_with_zero(self):
ops = """
[i0, i1]
More information about the Pypy-commit
mailing list