[pypy-svn] r66412 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Jul 19 17:59:28 CEST 2009
Author: arigo
Date: Sun Jul 19 17:59:26 2009
New Revision: 66412
Modified:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py
Log:
Simplify optimizefindnode by not tracking FixedClassSpecNodes
any more. Solves the bugs basically by removing them. I think
that we might need another approach to track FixedClassSpecNodes;
for now I will just focus on Virtuals.
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py Sun Jul 19 17:59:26 2009
@@ -1,6 +1,5 @@
from pypy.jit.metainterp.specnode import SpecNode
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
-from pypy.jit.metainterp.specnode import FixedClassSpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
from pypy.jit.metainterp.history import AbstractValue
from pypy.jit.metainterp.resoperation import rop
@@ -18,14 +17,16 @@
the field's status at the start and 'curfields' that represents it
at the current point (== the end when the first phase is complete).
"""
+ escaped = False # if True, then all the rest of the info is pointless
+ unique = UNIQUE_UNKNOWN # for find_unique_nodes()
+
+ # fields used to store the shape of the potential Virtual
+ knownclsbox = None
origfields = None # optimization; equivalent to an empty dict
curfields = None # optimization; equivalent to an empty dict
dependencies = None
- knownclsbox = None
- unique = UNIQUE_UNKNOWN # for find_unique_nodes()
- def __init__(self, escaped, fromstart=False):
- self.escaped = escaped
+ def __init__(self, fromstart=False):
self.fromstart = fromstart
def add_escape_dependency(self, other):
@@ -68,7 +69,8 @@
class NodeFinder(object):
"""Abstract base class."""
- node_escaped = InstanceNode(escaped=True)
+ node_escaped = InstanceNode()
+ node_escaped.escaped = True
def __init__(self):
self.nodes = {} # Box -> InstanceNode
@@ -93,7 +95,7 @@
self.getnode(box).mark_escaped()
def find_nodes_NEW_WITH_VTABLE(self, op):
- instnode = InstanceNode(escaped=False)
+ instnode = InstanceNode()
instnode.knownclsbox = op.args[0]
self.nodes[op.result] = instnode
@@ -119,36 +121,28 @@
fieldnode = instnode.curfields[field]
elif instnode.origfields is not None and field in instnode.origfields:
fieldnode = instnode.origfields[field]
- else:
- fieldnode = InstanceNode(escaped=False,
- fromstart=instnode.fromstart)
+ elif instnode.fromstart:
+ fieldnode = InstanceNode(fromstart=True)
instnode.add_escape_dependency(fieldnode)
if instnode.origfields is None:
instnode.origfields = av_newdict()
instnode.origfields[field] = fieldnode
+ else:
+ return # nothing to be gained from tracking the field
self.nodes[op.result] = fieldnode
def find_nodes_GETFIELD_GC_PURE(self, op):
self.find_nodes_GETFIELD_GC(op)
- def find_nodes_GUARD_CLASS(self, op):
- instbox = op.args[0]
- clsbox = op.args[1]
- try:
- instnode = self.nodes[instbox]
- except KeyError:
- instnode = self.nodes[instbox] = InstanceNode(escaped=True)
- assert instnode is not self.node_escaped
- assert (instnode.knownclsbox is None or
- instnode.knownclsbox.equals(clsbox))
- instnode.knownclsbox = clsbox
-
def find_nodes_JUMP(self, op):
# only set up the 'unique' field of the InstanceNodes;
# real handling comes later (build_result_specnodes() for loops).
for box in op.args:
self.getnode(box).set_unique_nodes()
+ def find_nodes_GUARD_CLASS(self, op):
+ pass # prevent default handling
+
def find_nodes_FAIL(self, op):
xxx
@@ -158,6 +152,7 @@
# Perfect specialization -- for loops only
class PerfectSpecializationFinder(NodeFinder):
+ node_fromstart = InstanceNode(fromstart=True)
def find_nodes_loop(self, loop):
self.setup_input_nodes(loop.inputargs)
@@ -167,7 +162,7 @@
def setup_input_nodes(self, inputargs):
inputnodes = []
for box in inputargs:
- instnode = InstanceNode(escaped=False, fromstart=True)
+ instnode = InstanceNode(fromstart=True)
inputnodes.append(instnode)
self.nodes[box] = instnode
self.inputnodes = inputnodes
@@ -187,15 +182,8 @@
def intersect(self, inputnode, exitnode):
assert inputnode.fromstart
if exitnode.unique == UNIQUE_NO or inputnode.escaped:
- # give a NotSpecNode or a FixedClassSpecNode
- if (inputnode.knownclsbox is not None and
- exitnode.knownclsbox is not None and
- inputnode.knownclsbox.equals(exitnode.knownclsbox)):
- # the class is known at the end, needed at the input,
- # and matches
- return FixedClassSpecNode(inputnode.knownclsbox)
- else:
- return prebuiltNotSpecNode
+ # give a NotSpecNode
+ return prebuiltNotSpecNode
#
assert exitnode.unique == UNIQUE_YES
if (inputnode.knownclsbox is not None and
@@ -217,7 +205,7 @@
# field stored at exit, but not read at input. Must
# still be allocated, otherwise it will be incorrectly
# uninitialized after a guard failure.
- node = InstanceNode(escaped=False, fromstart=True)
+ node = self.node_fromstart
specnode = self.intersect(node, d[ofs])
fields.append((ofs, specnode))
return VirtualInstanceSpecNode(exitnode.knownclsbox, fields)
@@ -233,22 +221,13 @@
class __extend__(NotSpecNode):
def make_instance_node(self):
- return InstanceNode(escaped=True)
+ return NodeFinder.node_escaped
def matches_instance_node(self, exitnode):
return True
-class __extend__(FixedClassSpecNode):
- def make_instance_node(self):
- instnode = InstanceNode(escaped=True)
- instnode.knownclsbox = self.known_class
- return instnode
- def matches_instance_node(self, exitnode):
- return (exitnode.knownclsbox is not None and
- self.known_class.equals(exitnode.knownclsbox))
-
class __extend__(VirtualInstanceSpecNode):
def make_instance_node(self):
- instnode = InstanceNode(escaped=False)
+ instnode = InstanceNode()
instnode.knownclsbox = self.known_class
instnode.curfields = av_newdict()
for ofs, subspecnode in self.fields:
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py Sun Jul 19 17:59:26 2009
@@ -19,18 +19,9 @@
prebuiltNotSpecNode = NotSpecNode()
-class FixedClassSpecNode(SpecNode):
- def __init__(self, known_class):
- self.known_class = known_class
-
- def _equals(self, other): # for tests only
- return (type(other) is FixedClassSpecNode and
- self.known_class.equals(other.known_class))
-
-
-class VirtualInstanceSpecNode(FixedClassSpecNode):
+class VirtualInstanceSpecNode(SpecNode):
def __init__(self, known_class, fields):
- FixedClassSpecNode.__init__(self, known_class)
+ self.known_class = known_class
self.fields = fields
def _equals(self, other): # for tests only
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Jul 19 17:59:26 2009
@@ -12,7 +12,6 @@
from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
from pypy.jit.metainterp.optimizeutil import sort_descrs
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
-from pypy.jit.metainterp.specnode import FixedClassSpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
from pypy.jit.metainterp.test.oparser import parse
@@ -144,8 +143,6 @@
self.cpu)
else:
return ConstObj(ootype.cast_to_object(cls_vtable))
- def makeFixed(cls_vtable):
- return FixedClassSpecNode(constclass(cls_vtable))
def makeVirtual(cls_vtable, **kwds_fields):
fields = []
for key, value in kwds_fields.items():
@@ -154,7 +151,6 @@
return VirtualInstanceSpecNode(constclass(cls_vtable), fields)
#
context = {'Not': prebuiltNotSpecNode,
- 'Fixed': makeFixed,
'Virtual': makeVirtual}
lst = eval('[' + text + ']', self.namespace, context)
return lst
@@ -230,119 +226,6 @@
assert getnode(boxes.p3).fromstart
assert not getnode(boxes.p4).fromstart
- def test_find_nodes_guard_class_1(self):
- ops = """
- [p1]
- guard_class(p1, ConstClass(node_vtable))
- fail()
- jump(p1)
- """
- boxes, getnode = self.find_nodes(ops, 'Fixed(node_vtable)')
- boxp1 = getnode(boxes.p1)
- assert boxp1.knownclsbox.value == self.node_vtable_adr
-
- def test_find_nodes_guard_class_2(self):
- ops = """
- [p1]
- p2 = getfield_gc(p1, descr=nextdescr)
- guard_class(p2, ConstClass(node_vtable))
- fail()
- jump(p1)
- """
- boxes, getnode = self.find_nodes(ops, 'Not')
- boxp1 = getnode(boxes.p1)
- boxp2 = getnode(boxes.p2)
- assert boxp1.knownclsbox is None
- assert boxp2.knownclsbox.value == self.node_vtable_adr
-
- def test_find_nodes_guard_class_outonly(self):
- ops = """
- [p1]
- p2 = escape()
- guard_class(p2, ConstClass(node_vtable))
- fail()
- jump(p2)
- """
- boxes, getnode = self.find_nodes(ops, 'Not')
- boxp1 = getnode(boxes.p1)
- boxp2 = getnode(boxes.p2)
- assert boxp1.knownclsbox is None
- assert boxp2.knownclsbox.value == self.node_vtable_adr
-
- def test_find_nodes_guard_class_inonly(self):
- ops = """
- [p1]
- guard_class(p1, ConstClass(node_vtable))
- fail()
- p2 = escape()
- jump(p2)
- """
- boxes, getnode = self.find_nodes(ops, 'Not')
- boxp1 = getnode(boxes.p1)
- boxp2 = getnode(boxes.p2)
- assert boxp1.knownclsbox.value == self.node_vtable_adr
- assert boxp2.knownclsbox is None
-
- def test_find_nodes_guard_class_inout(self):
- ops = """
- [p1]
- guard_class(p1, ConstClass(node_vtable))
- fail()
- p2 = escape()
- guard_class(p2, ConstClass(node_vtable))
- fail()
- jump(p2)
- """
- boxes, getnode = self.find_nodes(ops, 'Fixed(node_vtable)')
- boxp1 = getnode(boxes.p1)
- boxp2 = getnode(boxes.p2)
- assert boxp1.knownclsbox.value == self.node_vtable_adr
- assert boxp2.knownclsbox.value == self.node_vtable_adr
-
- def test_find_nodes_guard_class_mismatch(self):
- ops = """
- [p1]
- guard_class(p1, ConstClass(node_vtable))
- fail()
- p2 = escape()
- guard_class(p2, ConstClass(node_vtable2))
- fail()
- jump(p2)
- """
- boxes, getnode = self.find_nodes(ops, 'Not')
- boxp1 = getnode(boxes.p1)
- boxp2 = getnode(boxes.p2)
- assert boxp1.knownclsbox.value == self.node_vtable_adr
- assert boxp2.knownclsbox.value == self.node_vtable_adr2
-
- def test_find_nodes_guard_class_bug(self):
- py.test.skip("oups")
- ops = """
- [p1]
- p2 = escape()
- setfield_gc(p1, p2, descr=nextdescr)
- p3 = getfield_gc(p1, descr=nextdescr)
- guard_class(p3, ConstClass(node_vtable))
- fail()
- jump(p1)
- """
- self.find_nodes(ops, 'Not')
-
- def test_find_nodes_external_change(self):
- py.test.skip("oups")
- ops = """
- [p0, p3]
- guard_class(p3, ConstClass(node_vtable))
- fail()
- p1 = getfield_gc(p0, descr=nextdescr)
- guard_class(p1, ConstClass(node_vtable))
- fail()
- escape() # might change the field!
- p2 = getfield_gc(p0, descr=nextdescr)
- jump(p0, p2)
- """
- self.find_nodes(ops, 'Not, Not')
-
def test_find_nodes_new_1(self):
ops = """
[p1]
@@ -422,7 +305,6 @@
assert not boxp2.fromstart
assert not boxp3.fromstart
- assert boxp1.knownclsbox.value == self.node_vtable_adr
assert boxp2.knownclsbox.value == self.node_vtable_adr
assert boxp3.knownclsbox.value == self.node_vtable_adr2
@@ -454,7 +336,7 @@
"""
# the issue is the cycle "p2->p2", which cannot be represented
# with SpecNodes so far
- self.find_nodes(ops, 'Not, Fixed(node_vtable)',
+ self.find_nodes(ops, 'Not, Not',
boxkinds={'sum': BoxInt, 'sum2': BoxInt})
def test_find_nodes_new_aliasing_2(self):
@@ -469,6 +351,7 @@
self.find_nodes(ops, 'Not, Not')
def test_find_nodes_new_mismatch(self):
+ py.test.skip("gives a Virtual instead of Not -- not really wrong")
ops = """
[p1]
guard_class(p1, ConstClass(node_vtable))
@@ -488,7 +371,7 @@
p2 = new_with_vtable(ConstClass(node_vtable2), descr=nodesize2)
jump(p2, p2)
"""
- self.find_nodes(ops, 'Not, Fixed(node_vtable2)')
+ self.find_nodes(ops, 'Not, Not')
def test_find_nodes_new_escapes(self):
ops = """
@@ -549,12 +432,6 @@
jump(p0)
"""
self.find_bridge(ops, 'Not', 'Not')
- self.find_bridge(ops, 'Fixed(node_vtable)', 'Not')
- self.find_bridge(ops, 'Fixed(node_vtable)', 'Fixed(node_vtable)')
- #
- self.find_bridge(ops, 'Not', 'Fixed(node_vtable)', mismatch=True)
- self.find_bridge(ops, 'Fixed(node_vtable)', 'Fixed(node_vtable2)',
- mismatch=True)
def test_bridge_simple_virtual_1(self):
ops = """
@@ -564,7 +441,6 @@
jump(p0)
"""
self.find_bridge(ops, 'Not', 'Not')
- self.find_bridge(ops, 'Not', 'Fixed(node_vtable)')
self.find_bridge(ops, 'Not', 'Virtual(node_vtable, valuedescr=Not)')
self.find_bridge(ops, 'Not',
'''Virtual(node_vtable,
@@ -577,11 +453,6 @@
mismatch=True) # missing valuedescr
self.find_bridge(ops, 'Not', 'Virtual(node_vtable2, valuedescr=Not)',
mismatch=True) # bad class
- self.find_bridge(ops, 'Not',
- '''Virtual(node_vtable,
- valuedescr=Not,
- nextdescr=Fixed(node_vtable))''',
- mismatch=True) # nextdescr too precise
def test_bridge_simple_virtual_2(self):
ops = """
@@ -590,7 +461,6 @@
jump(p0)
"""
self.find_bridge(ops, 'Virtual(node_vtable)', 'Not')
- self.find_bridge(ops, 'Virtual(node_vtable)', 'Fixed(node_vtable)')
self.find_bridge(ops, 'Virtual(node_vtable)',
'Virtual(node_vtable, valuedescr=Not)')
self.find_bridge(ops, 'Virtual(node_vtable, valuedescr=Not)',
@@ -601,34 +471,16 @@
nextdescr=Not)''')
self.find_bridge(ops, '''Virtual(node_vtable,
valuedescr=Not,
- nextdescr=Fixed(node_vtable2))''',
- '''Virtual(node_vtable,
- valuedescr=Not,
- nextdescr=Fixed(node_vtable2))''')
- self.find_bridge(ops, '''Virtual(node_vtable,
- valuedescr=Not,
- nextdescr=Fixed(node_vtable2))''',
+ nextdescr=Not)''',
'''Virtual(node_vtable,
valuedescr=Not,
nextdescr=Not)''')
#
self.find_bridge(ops, 'Virtual(node_vtable)', 'Virtual(node_vtable)',
mismatch=True) # because of missing valuedescr
- self.find_bridge(ops, 'Virtual(node_vtable)', 'Fixed(node_vtable2)',
- mismatch=True) # bad class
self.find_bridge(ops, 'Virtual(node_vtable)',
'Virtual(node_vtable2, valuedescr=Not)',
mismatch=True) # bad class
- self.find_bridge(ops, 'Virtual(node_vtable, valuedescr=Not)',
- '''Virtual(node_vtable,
- valuedescr=Not,
- nextdescr=Fixed(node_vtable))''',
- mismatch=True) # unexpected nextdescr
- self.find_bridge(ops, 'Virtual(node_vtable, valuedescr=Not)',
- '''Virtual(node_vtable,
- valuedescr=Not,
- nextdescr=Virtual(node_vtable))''',
- mismatch=True) # unexpected nextdescr
def test_bridge_virtual_mismatch_1(self):
ops = """
@@ -638,9 +490,6 @@
jump(p0, p0)
"""
self.find_bridge(ops, 'Not', 'Not, Not')
- self.find_bridge(ops, 'Not', 'Not, Fixed(node_vtable)')
- self.find_bridge(ops, 'Not', 'Fixed(node_vtable), Not')
- self.find_bridge(ops, 'Not', 'Fixed(node_vtable), Fixed(node_vtable)')
#
self.find_bridge(ops, 'Not',
'''Virtual(node_vtable, valuedescr=Not),
@@ -656,15 +505,13 @@
jump(p2)
"""
self.find_bridge(ops, 'Not', 'Not')
- self.find_bridge(ops, 'Not', 'Fixed(node_vtable)')
- self.find_bridge(ops, 'Virtual(node_vtable2, nextdescr=Not)',
- 'Fixed(node_vtable)')
+ self.find_bridge(ops, 'Virtual(node_vtable2, nextdescr=Not)', 'Not')
self.find_bridge(ops,
'''Virtual(node_vtable,
nextdescr=Virtual(node_vtable,
- nextdescr=Fixed(node_vtable2)))''',
+ nextdescr=Not))''',
'''Virtual(node_vtable,
- nextdescr=Fixed(node_vtable2))''')
+ nextdescr=Not)''')
#
self.find_bridge(ops, 'Not', 'Virtual(node_vtable)',
mismatch=True)
More information about the Pypy-commit
mailing list