[pypy-svn] r66678 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Jul 29 20:00:41 CEST 2009
Author: arigo
Date: Wed Jul 29 20:00:39 2009
New Revision: 66678
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py
Log:
Start on virtual arrays.
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py Wed Jul 29 20:00:39 2009
@@ -1,15 +1,17 @@
from pypy.jit.metainterp.specnode import SpecNode
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.history import AbstractValue
+from pypy.jit.metainterp.specnode import VirtualArraySpecNode
+from pypy.jit.metainterp.history import AbstractValue, ConstInt
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs
# ____________________________________________________________
UNIQUE_UNKNOWN = '\x00'
-UNIQUE_YES = '\x01'
-UNIQUE_NO = '\x02'
+UNIQUE_NO = '\x01'
+UNIQUE_INST = '\x02'
+UNIQUE_ARRAY = '\x03'
class InstanceNode(object):
"""An instance of this class is used to match the start and
@@ -20,10 +22,17 @@
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 # set only on freshly-allocated structures
+ # fields used to store the shape of the potential VirtualInstance
+ knownclsbox = None # set only on freshly-allocated or fromstart structures
origfields = None # optimization; equivalent to an empty dict
curfields = None # optimization; equivalent to an empty dict
+
+ # fields used to store the shape of the potential VirtualList
+ arraydescr = None # set only on freshly-allocated or fromstart arrays
+ #arraysize = .. # valid if and only if arraydescr is not None
+ origitems = None # optimization; equivalent to an empty dict
+ curitems = None # optimization; equivalent to an empty dict
+
dependencies = None
def __init__(self, fromstart=False):
@@ -46,22 +55,29 @@
box.mark_escaped()
def set_unique_nodes(self):
- if (self.escaped or self.fromstart or self.knownclsbox is None
- or self.unique != UNIQUE_UNKNOWN):
+ if self.escaped or self.fromstart or self.unique != UNIQUE_UNKNOWN:
# this node is not suitable for being a virtual, or we
# encounter it more than once when doing the recursion
self.unique = UNIQUE_NO
- else:
- self.unique = UNIQUE_YES
+ elif self.knownclsbox is not None:
+ self.unique = UNIQUE_INST
if self.curfields is not None:
- for subnode in self.curfields.values():
+ for subnode in self.curfields.itervalues():
subnode.set_unique_nodes()
+ elif self.arraydescr is not None:
+ self.unique = UNIQUE_ARRAY
+ if self.curitems is not None:
+ for subnode in self.curitems.itervalues():
+ subnode.set_unique_nodes()
+ else:
+ self.unique = UNIQUE_NO
def __repr__(self):
flags = ''
if self.escaped: flags += 'e'
if self.fromstart: flags += 's'
if self.knownclsbox: flags += 'c'
+ if self.arraydescr: flags += str(self.arraysize)
return "<InstanceNode (%s)>" % (flags,)
# ____________________________________________________________
@@ -99,6 +115,15 @@
instnode.knownclsbox = op.args[0]
self.nodes[op.result] = instnode
+ def find_nodes_NEW_ARRAY(self, op):
+ lengthbox = op.args[0]
+ if not isinstance(lengthbox, ConstInt):
+ return # var-sized arrays are not virtual
+ arraynode = InstanceNode()
+ arraynode.arraysize = lengthbox.value
+ arraynode.arraydescr = op.descr
+ self.nodes[op.result] = arraynode
+
def find_nodes_GUARD_CLASS(self, op):
instnode = self.getnode(op.args[0])
if instnode.fromstart: # only useful in this case
@@ -137,8 +162,47 @@
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)
+ find_nodes_GETFIELD_GC_PURE = find_nodes_GETFIELD_GC
+
+ def find_nodes_SETARRAYITEM_GC(self, op):
+ indexbox = op.args[1]
+ if not isinstance(indexbox, ConstInt):
+ self.find_nodes_default(op) # not a Const index
+ return
+ arraynode = self.getnode(op.args[0])
+ itemnode = self.getnode(op.args[2])
+ if arraynode.escaped:
+ itemnode.mark_escaped()
+ return # nothing to be gained from tracking the item
+ if arraynode.curitems is None:
+ arraynode.curitems = {}
+ arraynode.curitems[indexbox.value] = itemnode
+ arraynode.add_escape_dependency(itemnode)
+
+ def find_nodes_GETARRAYITEM_GC(self, op):
+ indexbox = op.args[1]
+ if not isinstance(indexbox, ConstInt):
+ self.find_nodes_default(op) # not a Const index
+ return
+ arraynode = self.getnode(op.args[0])
+ if arraynode.escaped:
+ return # nothing to be gained from tracking the item
+ index = indexbox.value
+ if arraynode.curitems is not None and index in arraynode.curitems:
+ itemnode = arraynode.curitems[index]
+ elif arraynode.origitems is not None and index in arraynode.origitems:
+ itemnode = arraynode.origitems[index]
+ elif arraynode.fromstart:
+ itemnode = InstanceNode(fromstart=True)
+ arraynode.add_escape_dependency(itemnode)
+ if arraynode.origitems is None:
+ arraynode.origitems = {}
+ arraynode.origitems[index] = itemnode
+ else:
+ return # nothing to be gained from tracking the item
+ self.nodes[op.result] = itemnode
+
+ find_nodes_GETARRAYITEM_GC_PURE = find_nodes_GETARRAYITEM_GC
def find_nodes_JUMP(self, op):
# only set up the 'unique' field of the InstanceNodes;
@@ -188,11 +252,18 @@
def intersect(self, inputnode, exitnode):
assert inputnode.fromstart
- if exitnode.unique == UNIQUE_NO or inputnode.escaped:
- # give a NotSpecNode
+ if inputnode.escaped:
return prebuiltNotSpecNode
- #
- assert exitnode.unique == UNIQUE_YES
+ unique = exitnode.unique
+ if unique == UNIQUE_NO:
+ return prebuiltNotSpecNode
+ if unique == UNIQUE_INST:
+ return self.intersect_instance(inputnode, exitnode)
+ if unique == UNIQUE_ARRAY:
+ return self.intersect_array(inputnode, exitnode)
+ assert 0, "unknown value for exitnode.unique: %d" % ord(unique)
+
+ def intersect_instance(self, inputnode, exitnode):
if (inputnode.knownclsbox is not None and
not inputnode.knownclsbox.equals(exitnode.knownclsbox)):
# unique match, but the class is known to be a mismatch
@@ -224,6 +295,23 @@
fields.append((ofs, specnode))
return VirtualInstanceSpecNode(exitnode.knownclsbox, fields)
+ def intersect_array(self, inputnode, exitnode):
+ assert inputnode.arraydescr is None
+ #
+ items = []
+ for i in range(exitnode.arraysize):
+ if exitnode.curitems is None:
+ exitsubnode = self.node_escaped
+ else:
+ exitsubnode = exitnode.curitems.get(i, self.node_escaped)
+ if inputnode.origitems is None:
+ node = self.node_fromstart
+ else:
+ node = inputnode.origitems.get(i, self.node_fromstart)
+ specnode = self.intersect(node, exitsubnode)
+ items.append(specnode)
+ return VirtualArraySpecNode(exitnode.arraydescr, items)
+
# ____________________________________________________________
# A subclass of NodeFinder for bridges only
@@ -252,7 +340,7 @@
if exitnode.unique == UNIQUE_NO:
return False
#
- assert exitnode.unique == UNIQUE_YES
+ assert exitnode.unique == UNIQUE_INST
if not self.known_class.equals(exitnode.knownclsbox):
# unique match, but the class is known to be a mismatch
return False
@@ -273,6 +361,12 @@
return False # some key is in d but not in self.fields
return True
+class __extend__(VirtualArraySpecNode):
+ def make_instance_node(self):
+ xxx
+ def matches_instance_node(self):
+ xxx
+
class BridgeSpecializationFinder(NodeFinder):
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py Wed Jul 29 20:00:39 2009
@@ -13,6 +13,7 @@
from pypy.jit.metainterp.optimizeutil import sort_descrs
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
+from pypy.jit.metainterp.specnode import VirtualArraySpecNode
from pypy.jit.metainterp.test.oparser import parse
@@ -55,7 +56,6 @@
nextdescr = cpu.fielddescrof(NODE, 'next')
otherdescr = cpu.fielddescrof(NODE2, 'other')
- # for test_specnode
arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE),
@@ -85,6 +85,8 @@
nodesize = cpu.typedescrof(NODE)
nodesize2 = cpu.typedescrof(NODE2)
+ arraydescr = cpu.arraydescrof(ootype.Array(ootype.Signed))
+
# force a consistent order
valuedescr.sort_key()
nextdescr.sort_key()
@@ -114,9 +116,12 @@
fields.append((self.namespace[key], value))
fields.sort(key = lambda (x, _): x.sort_key())
return VirtualInstanceSpecNode(constclass(cls_vtable), fields)
+ def makeVirtualArray(arraydescr, *items):
+ return VirtualArraySpecNode(arraydescr, items)
#
context = {'Not': prebuiltNotSpecNode,
- 'Virtual': makeVirtual}
+ 'Virtual': makeVirtual,
+ 'VArray': makeVirtualArray}
lst = eval('[' + text + ']', self.namespace, context)
return lst
@@ -499,6 +504,40 @@
"""
self.find_nodes(ops, 'Not, Not')
+ def test_find_nodes_array_virtual_1(self):
+ ops = """
+ [i1, p2]
+ i2 = getarrayitem_gc(p2, 1, descr=arraydescr)
+ escape(i2)
+ p3 = new_array(3, descr=arraydescr)
+ setarrayitem_gc(p3, 1, i1, descr=arraydescr)
+ jump(i1, p3)
+ """
+ self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)')
+
+ def test_find_nodes_array_virtual_2(self):
+ ops = """
+ [i1, p2]
+ i2 = arraylen_gc(p2, descr=arraydescr)
+ escape(i2)
+ p3 = new_array(3, descr=arraydescr)
+ setarrayitem_gc(p3, 1, i1, descr=arraydescr)
+ jump(i1, p3)
+ """
+ self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)')
+
+ def test_find_nodes_array_nonvirtual_1(self):
+ ops = """
+ [i1, p2]
+ i2 = getarrayitem_gc(p2, i1, descr=arraydescr)
+ escape(i2)
+ p3 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p3, i1, i2, descr=arraydescr)
+ jump(i1, p3)
+ """
+ # Does not work because of the variable index, 'i1'.
+ self.find_nodes(ops, 'Not, Not')
+
# ------------------------------
# Bridge tests
More information about the Pypy-commit
mailing list