[pypy-svn] r67743 - in pypy/branch/optimize-novaluedep/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Sep 17 19:01:28 CEST 2009
Author: arigo
Date: Thu Sep 17 19:01:25 2009
New Revision: 67743
Modified:
pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py
pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py
pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py
pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
(arigo, cfbolz): start tracking again loops that are not efficient at all.
Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py Thu Sep 17 19:01:25 2009
@@ -8,6 +8,7 @@
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.executor import _execute_nonspec
from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
# ____________________________________________________________
@@ -341,9 +342,11 @@
def intersect(self, inputnode, exitnode):
assert inputnode.fromstart
if inputnode.is_constant() and \
- exitnode.is_constant() and \
- inputnode.knownvaluebox.same_constant(exitnode.knownvaluebox):
- return ConstantSpecNode(inputnode.knownvaluebox)
+ exitnode.is_constant():
+ if inputnode.knownvaluebox.same_constant(exitnode.knownvaluebox):
+ return ConstantSpecNode(inputnode.knownvaluebox)
+ else:
+ raise InvalidLoop
if inputnode.escaped:
return prebuiltNotSpecNode
unique = exitnode.unique
@@ -387,7 +390,7 @@
if (inputnode.knownclsbox is not None and
not inputnode.knownclsbox.same_constant(exitnode.knownclsbox)):
# unique match, but the class is known to be a mismatch
- return prebuiltNotSpecNode
+ raise InvalidLoop
#
fields = self.compute_common_fields(inputnode.origfields,
exitnode.curfields)
Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py Thu Sep 17 19:01:25 2009
@@ -8,6 +8,7 @@
from pypy.jit.metainterp.specnode import VirtualArraySpecNode
from pypy.jit.metainterp.specnode import VirtualStructSpecNode
from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
from pypy.jit.metainterp import resume, compile
from pypy.jit.metainterp.typesystem import llhelper, oohelper
from pypy.rlib.objectmodel import we_are_translated
@@ -484,7 +485,7 @@
for i in range(len(op.args)):
arg = op.args[i]
if arg in self.values:
- box = self.values[arg].force_box() # I think we definitely need box, at least for this but it's unclear I mean is it ok to replace box with Const(..) when we set level==CONSTANT?ah, in this direction. yes, I would expect that to be ok ah yes indeed I see it
+ box = self.values[arg].force_box()
if box is not arg:
if must_clone:
op = op.clone()
@@ -578,7 +579,8 @@
if value.is_constant():
box = value.box
assert isinstance(box, Const)
- assert box.same_constant(constbox)
+ if not box.same_constant(constbox):
+ raise InvalidLoop
return
self.emit_operation(op)
value.make_constant(constbox)
@@ -600,6 +602,9 @@
assert isinstance(expectedclassbox, Const)
realclassbox = value.get_constant_class(self.cpu)
if realclassbox is not None:
+ # the following assert should always be true for now,
+ # because invalid loops that would fail it are detected
+ # earlier, in optimizefindnode.py.
assert realclassbox.same_constant(expectedclassbox)
return
self.emit_operation(op)
Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py (original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py Thu Sep 17 19:01:25 2009
@@ -2,6 +2,11 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.jit.metainterp import resoperation
+class InvalidLoop(Exception):
+ """Raised when the optimize*.py detect that the loop that
+ we are trying to build cannot possibly make sense as a
+ long-running loop (e.g. it cannot run 2 complete iterations)."""
+
# ____________________________________________________________
# Misc. utilities
Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py (original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py Thu Sep 17 19:01:25 2009
@@ -10,7 +10,7 @@
ConstObj, AbstractDescr)
from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
-from pypy.jit.metainterp.optimizeutil import sort_descrs
+from pypy.jit.metainterp.optimizeutil import sort_descrs, InvalidLoop
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
from pypy.jit.metainterp.specnode import VirtualArraySpecNode
@@ -417,9 +417,9 @@
p2 = new_with_vtable(ConstClass(node_vtable2))
jump(p2)
"""
- # this must give 'Not', not 'Virtual', because optimizeopt.py would
- # remove the guard_class for a virtual.
- self.find_nodes(ops, 'Not')
+ # this is not a valid loop at all, because of the mismatch
+ # between the produced and the consumed class.
+ py.test.raises(InvalidLoop, self.find_nodes, ops, None)
def test_find_nodes_new_aliasing_mismatch(self):
ops = """
@@ -431,6 +431,8 @@
p2 = new_with_vtable(ConstClass(node_vtable2))
jump(p2, p2)
"""
+ # this is also not really a valid loop, but it's not detected
+ # because p2 is passed more than once in the jump().
self.find_nodes(ops, 'Not, Not')
def test_find_nodes_new_escapes(self):
@@ -517,14 +519,14 @@
ops = """
[p0]
i0 = getfield_gc(p0, descr=valuedescr)
- guard_value(i0, 0)
+ guard_value(i0, 5)
fail()
p1 = new_with_vtable(ConstClass(node_vtable))
# the field 'value' has its default value of 0
jump(p1)
"""
# The answer must contain the 'value' field, because otherwise
- # we might get incorrect results: when tracing, maybe i0 was not 0.
+ # we might get incorrect results: when tracing, i0 was 5.
self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
def test_find_nodes_nonvirtual_guard_class(self):
@@ -721,6 +723,15 @@
"""
self.find_nodes(ops, 'Constant(myptr)')
+ def test_find_nodes_guard_value_constant_mismatch(self):
+ ops = """
+ [p1]
+ guard_value(p1, ConstPtr(myptr2))
+ fail()
+ jump(ConstPtr(myptr))
+ """
+ py.test.raises(InvalidLoop, self.find_nodes, ops, None)
+
def test_find_nodes_guard_value_escaping_constant(self):
ops = """
[p1]
@@ -889,19 +900,6 @@
"""
self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
- def test_bug_2(self):
- py.test.skip("fix me")
- ops = """
- [p1]
- i1 = ooisnull(p1)
- guard_true(i1)
- fail()
- #
- p2 = new_with_vtable(ConstClass(node_vtable))
- jump(p2)
- """
- self.find_nodes(ops, 'Not',
- i1=1)
# ------------------------------
# Bridge tests
Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py Thu Sep 17 19:01:25 2009
@@ -7,6 +7,7 @@
BaseTest)
from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
from pypy.jit.metainterp.optimizeopt import optimize_loop_1
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
from pypy.jit.metainterp.history import AbstractDescr, ConstInt
from pypy.jit.metainterp import resume, executor, compile
from pypy.jit.metainterp.resoperation import rop, opname
@@ -221,22 +222,26 @@
def test_remove_consecutive_guard_value_constfold(self):
ops = """
- [i0]
+ []
+ i0 = escape()
guard_value(i0, 0)
fail()
i1 = int_add(i0, 1)
guard_value(i1, 1)
fail()
i2 = int_add(i1, 2)
- jump(i2)
+ escape(i2)
+ jump()
"""
expected = """
- [i0]
+ []
+ i0 = escape()
guard_value(i0, 0)
- fail()
- jump(3)
+ fail()
+ escape(3)
+ jump()
"""
- self.optimize_loop(ops, 'Not', expected)
+ self.optimize_loop(ops, '', expected)
def test_remove_guard_value_if_constant(self):
ops = """
@@ -1238,6 +1243,33 @@
self.optimize_loop(ops, 'Not, VArray(arraydescr2, Not)',
expected)
+ def test_invalid_loop_1(self):
+ ops = """
+ [p1]
+ i1 = ooisnull(p1)
+ guard_true(i1)
+ fail()
+ #
+ p2 = new_with_vtable(ConstClass(node_vtable))
+ jump(p2)
+ """
+ py.test.raises(InvalidLoop, self.optimize_loop,
+ ops, 'Virtual(node_vtable)', None)
+
+ def test_invalid_loop_2(self):
+ py.test.skip("this would fail if we had Fixed again in the specnodes")
+ ops = """
+ [p1]
+ guard_class(p1, ConstClass(node_vtable2))
+ fail()
+ #
+ p2 = new_with_vtable(ConstClass(node_vtable))
+ escape(p2) # prevent it from staying Virtual
+ jump(p2)
+ """
+ py.test.raises(InvalidLoop, self.optimize_loop,
+ ops, '...', None)
+
# ----------
def make_fail_descr(self):
More information about the Pypy-commit
mailing list