[pypy-svn] r66694 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Jul 30 13:33:13 CEST 2009
Author: arigo
Date: Thu Jul 30 13:33:12 2009
New Revision: 66694
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimizefindnode.py
Log:
Support rop.NEW in optimizefindnode.
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 Thu Jul 30 13:33:12 2009
@@ -2,6 +2,7 @@
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.specnode import VirtualStructSpecNode
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
@@ -12,6 +13,7 @@
UNIQUE_NO = '\x01'
UNIQUE_INST = '\x02'
UNIQUE_ARRAY = '\x03'
+UNIQUE_STRUCT = '\x04'
class InstanceNode(object):
"""An instance of this class is used to match the start and
@@ -33,6 +35,11 @@
origitems = None # optimization; equivalent to an empty dict
curitems = None # optimization; equivalent to an empty dict
+ # fields used to store the sahpe of the potential VirtualStruct
+ structdescr = None # set only on freshly-allocated or fromstart structs
+ #origfields = .. # same as above
+ #curfields = .. # same as above
+
dependencies = None
def __init__(self, fromstart=False):
@@ -69,6 +76,11 @@
if self.curitems is not None:
for subnode in self.curitems.itervalues():
subnode.set_unique_nodes()
+ elif self.structdescr is not None:
+ self.unique = UNIQUE_STRUCT
+ if self.curfields is not None:
+ for subnode in self.curfields.itervalues():
+ subnode.set_unique_nodes()
else:
self.unique = UNIQUE_NO
@@ -78,6 +90,7 @@
if self.fromstart: flags += 's'
if self.knownclsbox: flags += 'c'
if self.arraydescr: flags += str(self.arraysize)
+ if self.structdescr: flags += 'S'
return "<InstanceNode (%s)>" % (flags,)
# ____________________________________________________________
@@ -124,6 +137,11 @@
instnode.knownclsbox = op.args[0]
self.nodes[op.result] = instnode
+ def find_nodes_NEW(self, op):
+ instnode = InstanceNode()
+ instnode.structdescr = op.descr
+ self.nodes[op.result] = instnode
+
def find_nodes_NEW_ARRAY(self, op):
lengthbox = op.args[0]
if not isinstance(lengthbox, ConstInt):
@@ -270,31 +288,27 @@
return self.intersect_instance(inputnode, exitnode)
if unique == UNIQUE_ARRAY:
return self.intersect_array(inputnode, exitnode)
+ if unique == UNIQUE_STRUCT:
+ return self.intersect_struct(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
- return prebuiltNotSpecNode
- #
+ def compute_common_fields(self, orig, d):
fields = []
- d = exitnode.curfields
- if inputnode.origfields is not None:
+ if orig is not None:
if d is not None:
d = d.copy()
else:
d = av_newdict()
- for ofs in inputnode.origfields:
+ for ofs in orig:
d.setdefault(ofs, self.node_escaped)
if d is not None:
lst = d.keys()
sort_descrs(lst)
for ofs in lst:
try:
- if inputnode.origfields is None:
+ if orig is None:
raise KeyError
- node = inputnode.origfields[ofs]
+ node = orig[ofs]
except KeyError:
# field stored at exit, but not read at input. Must
# still be allocated, otherwise it will be incorrectly
@@ -302,6 +316,16 @@
node = self.node_fromstart
specnode = self.intersect(node, d[ofs])
fields.append((ofs, specnode))
+ return fields
+
+ 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
+ return prebuiltNotSpecNode
+ #
+ fields = self.compute_common_fields(inputnode.origfields,
+ exitnode.curfields)
return VirtualInstanceSpecNode(exitnode.knownclsbox, fields)
def intersect_array(self, inputnode, exitnode):
@@ -321,6 +345,13 @@
items.append(specnode)
return VirtualArraySpecNode(exitnode.arraydescr, items)
+ def intersect_struct(self, inputnode, exitnode):
+ assert inputnode.structdescr is None
+ #
+ fields = self.compute_common_fields(inputnode.origfields,
+ exitnode.curfields)
+ return VirtualStructSpecNode(exitnode.structdescr, fields)
+
# ____________________________________________________________
# A subclass of NodeFinder for bridges only
@@ -354,21 +385,23 @@
# unique match, but the class is known to be a mismatch
return False
#
- d = exitnode.curfields
- seen = 0
- for ofs, subspecnode in self.fields:
- try:
- if d is None:
- raise KeyError
- instnode = d[ofs]
- seen += 1
- except KeyError:
- instnode = NodeFinder.node_escaped
- if not subspecnode.matches_instance_node(instnode):
- return False
- if d is not None and len(d) > seen:
- return False # some key is in d but not in self.fields
- return True
+ return matches_fields(self.fields, exitnode.curfields)
+
+def matches_fields(fields, d):
+ seen = 0
+ for ofs, subspecnode in fields:
+ try:
+ if d is None:
+ raise KeyError
+ instnode = d[ofs]
+ seen += 1
+ except KeyError:
+ instnode = NodeFinder.node_escaped
+ if not subspecnode.matches_instance_node(instnode):
+ return False
+ if d is not None and len(d) > seen:
+ return False # some key is in d but not in fields
+ return True
class __extend__(VirtualArraySpecNode):
def make_instance_node(self):
@@ -396,6 +429,19 @@
return False
return True
+class __extend__(VirtualStructSpecNode):
+ def make_instance_node(self):
+ raise AssertionError, "not implemented (but not used actually)"
+ def matches_instance_node(self, exitnode):
+ if exitnode.unique == UNIQUE_NO:
+ return False
+ #
+ assert exitnode.unique == UNIQUE_STRUCT
+ assert self.typedescr == exitnode.structdescr
+ #
+ return matches_fields(self.fields, exitnode.curfields)
+
+
class BridgeSpecializationFinder(NodeFinder):
def find_nodes_bridge(self, bridge, specnodes=None):
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 Thu Jul 30 13:33:12 2009
@@ -14,6 +14,7 @@
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.specnode import VirtualStructSpecNode
from pypy.jit.metainterp.test.oparser import parse
@@ -124,18 +125,25 @@
self.cpu)
else:
return ConstObj(ootype.cast_to_object(cls_vtable))
- def makeVirtual(cls_vtable, **kwds_fields):
+ def parsefields(kwds_fields):
fields = []
for key, value in kwds_fields.items():
fields.append((self.namespace[key], value))
fields.sort(key = lambda (x, _): x.sort_key())
+ return fields
+ def makeVirtual(cls_vtable, **kwds_fields):
+ fields = parsefields(kwds_fields)
return VirtualInstanceSpecNode(constclass(cls_vtable), fields)
def makeVirtualArray(arraydescr, *items):
return VirtualArraySpecNode(arraydescr, items)
+ def makeVirtualStruct(typedescr, **kwds_fields):
+ fields = parsefields(kwds_fields)
+ return VirtualStructSpecNode(typedescr, fields)
#
context = {'Not': prebuiltNotSpecNode,
'Virtual': makeVirtual,
- 'VArray': makeVirtualArray}
+ 'VArray': makeVirtualArray,
+ 'VStruct': makeVirtualStruct}
lst = eval('[' + text + ']', self.namespace, context)
return lst
@@ -564,6 +572,28 @@
# escapes because getarrayitem_gc uses a non-constant index
self.find_nodes(ops, 'Not, Not')
+ def test_find_nodes_struct_virtual_1(self):
+ ops = """
+ [i1, p2]
+ i2 = getfield_gc(p2, descr=adescr)
+ escape(i2)
+ p3 = new(descr=ssize)
+ setfield_gc(p3, i1, descr=adescr)
+ jump(i1, p3)
+ """
+ self.find_nodes(ops, 'Not, VStruct(ssize, adescr=Not)')
+
+ def test_find_nodes_struct_nonvirtual_1(self):
+ ops = """
+ [i1, p2]
+ i2 = getfield_gc(p2, descr=adescr)
+ escape(p2)
+ p3 = new(descr=ssize)
+ setfield_gc(p3, i1, descr=adescr)
+ jump(i1, p3)
+ """
+ self.find_nodes(ops, 'Not, Not')
+
# ------------------------------
# Bridge tests
More information about the Pypy-commit
mailing list