[pypy-svn] r66365 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Jul 18 19:01:34 CEST 2009
Author: arigo
Date: Sat Jul 18 19:01:33 2009
New Revision: 66365
Added:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py
- copied, changed from r66363, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeloop.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py
- copied, changed from r66363, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeloop.py
Removed:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeloop.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeloop.py
Modified:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
Log:
Reorganize things a bit yet another time.
Start on the BridgeSpecializationFinder; only one test passing.
Copied: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py (from r66363, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeloop.py)
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeloop.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizefindnode.py Sat Jul 18 19:01:33 2009
@@ -1,7 +1,9 @@
-from pypy.jit.metainterp.specnode import prebuiltNotSpecNode
+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
from pypy.jit.metainterp.optimize import av_newdict, _findall, sort_descrs
# ____________________________________________________________
@@ -42,6 +44,18 @@
for box in deps:
box.mark_escaped()
+ def set_unique_nodes(self):
+ if (self.escaped or self.fromstart or self.knownclsbox is None
+ 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
+ if self.curfields is not None:
+ for subnode in self.curfields.values():
+ subnode.set_unique_nodes()
+
def __repr__(self):
flags = ''
if self.escaped: flags += 'e'
@@ -49,8 +63,11 @@
if self.knownclsbox: flags += 'c'
return "<InstanceNode (%s)>" % (flags,)
+# ____________________________________________________________
+# General find_nodes_xxx() interface, for both loops and bridges
-class PerfectSpecializationFinder(object):
+class NodeFinder(object):
+ """Abstract base class."""
node_escaped = InstanceNode(escaped=True)
def __init__(self):
@@ -59,15 +76,8 @@
def getnode(self, box):
return self.nodes.get(box, self.node_escaped)
- def find_nodes(self, loop):
- inputnodes = []
- for box in loop.inputargs:
- instnode = InstanceNode(escaped=False, fromstart=True)
- inputnodes.append(instnode)
- self.nodes[box] = instnode
- self.inputnodes = inputnodes
- #
- for op in loop.operations:
+ def find_nodes(self, operations):
+ for op in operations:
opnum = op.opnum
for value, func in find_nodes_ops:
if opnum == value:
@@ -134,11 +144,38 @@
instnode.knownclsbox = clsbox
def find_nodes_JUMP(self, op):
- """Build the list of specnodes based on the result
- computed by this PerfectSpecializationFinder.
- """
+ # only set up the 'unique' field of the InstanceNodes;
+ # real handling comes later (build_result_specnodes() for loops).
for box in op.args:
- self.find_unique_nodes(self.getnode(box))
+ self.getnode(box).set_unique_nodes()
+
+ def find_nodes_FAIL(self, op):
+ xxx
+
+find_nodes_ops = _findall(NodeFinder, 'find_nodes_')
+
+# ____________________________________________________________
+# Perfect specialization -- for loops only
+
+class PerfectSpecializationFinder(NodeFinder):
+
+ def find_nodes_loop(self, loop):
+ self.setup_input_nodes(loop.inputargs)
+ self.find_nodes(loop.operations)
+ self.build_result_specnodes(loop.operations[-1])
+
+ def setup_input_nodes(self, inputargs):
+ inputnodes = []
+ for box in inputargs:
+ instnode = InstanceNode(escaped=False, fromstart=True)
+ inputnodes.append(instnode)
+ self.nodes[box] = instnode
+ self.inputnodes = inputnodes
+
+ def build_result_specnodes(self, op):
+ # Build the list of specnodes based on the result
+ # computed by NodeFinder.find_nodes().
+ assert op.opnum == rop.JUMP
specnodes = []
assert len(self.inputnodes) == len(op.args)
for i in range(len(op.args)):
@@ -147,19 +184,6 @@
specnodes.append(self.intersect(inputnode, exitnode))
self.specnodes = specnodes
- def find_unique_nodes(self, exitnode):
- if (exitnode.escaped or exitnode.fromstart
- or exitnode.knownclsbox is None
- or exitnode.unique != UNIQUE_UNKNOWN):
- # the exitnode is not suitable for being a virtual, or we
- # encounter it more than once when doing the recursion
- exitnode.unique = UNIQUE_NO
- else:
- exitnode.unique = UNIQUE_YES
- if exitnode.curfields is not None:
- for subnode in exitnode.curfields.values():
- self.find_unique_nodes(subnode)
-
def intersect(self, inputnode, exitnode):
assert inputnode.fromstart
if exitnode.unique == UNIQUE_NO or inputnode.escaped:
@@ -198,4 +222,56 @@
fields.append((ofs, specnode))
return VirtualInstanceSpecNode(exitnode.knownclsbox, fields)
-find_nodes_ops = _findall(PerfectSpecializationFinder, 'find_nodes_')
+# ____________________________________________________________
+# A subclass of NodeFinder for bridges only
+
+class __extend__(SpecNode):
+ def make_instance_node(self):
+ raise NotImplementedError
+ def matches_instance_node(self, exitnode):
+ raise NotImplementedError
+
+class __extend__(NotSpecNode):
+ def make_instance_node(self):
+ 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):
+ xxx
+
+class __extend__(VirtualInstanceSpecNode):
+ def make_instance_node(self):
+ instnode = InstanceNode(escaped=False)
+ instnode.curfields = av_newdict()
+ for ofs, subspecnode in self.fields:
+ instnode.curfields[ofs] = subspecnode.make_instance_node()
+ return instnode
+ def matches_instance_node(self, exitnode):
+ if exitnode.unique == UNIQUE_NO:
+ return False
+ else:
+ xxx
+
+class BridgeSpecializationFinder(NodeFinder):
+
+ def setup_bridge_input_nodes(self, specnodes, inputargs):
+ assert len(specnodes) == len(inputargs)
+ for i in range(len(inputargs)):
+ instnode = specnodes[i].make_instance_node()
+ box = inputargs[i]
+ self.nodes[box] = instnode
+
+ def bridge_matches(self, jump_op, nextloop_specnodes):
+ assert jump_op.opnum == rop.JUMP
+ assert len(jump_op.args) == len(nextloop_specnodes)
+ for i in range(len(nextloop_specnodes)):
+ exitnode = self.getnode(jump_op.args[i])
+ if not nextloop_specnodes[i].matches_instance_node(exitnode):
+ return False
+ return True
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 Sat Jul 18 19:01:33 2009
@@ -1,6 +1,8 @@
+from pypy.tool.pairtype import extendabletype
class SpecNode(object):
+ __metaclass__ = extendabletype # extended in optimizefindnode.py
__slots__ = ()
def extract_runtime_data(self, cpu, valuebox, resultlist):
Copied: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py (from r66363, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeloop.py)
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeloop.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizefindnode.py Sat Jul 18 19:01:33 2009
@@ -8,7 +8,8 @@
from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
Const, ConstAddr, TreeLoop, BoxObj,
ConstObj, AbstractDescr)
-from pypy.jit.metainterp.optimizeloop import PerfectSpecializationFinder
+from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
+from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
from pypy.jit.metainterp.optimize import sort_descrs
from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
from pypy.jit.metainterp.specnode import FixedClassSpecNode
@@ -135,7 +136,7 @@
equaloplists(optimized.operations,
self.parse(expected).operations)
- def assert_specnodes(self, specnodes, text):
+ def unpack_specnodes(self, text):
#
def constclass(cls_vtable):
if self.type_system == 'lltype':
@@ -156,6 +157,10 @@
'Fixed': makeFixed,
'Virtual': makeVirtual}
lst = eval('[' + text + ']', self.namespace, context)
+ return lst
+
+ def check_specnodes(self, specnodes, text):
+ lst = self.unpack_specnodes(text)
assert len(specnodes) == len(lst)
for x, y in zip(specnodes, lst):
assert x._equals(y)
@@ -164,9 +169,8 @@
def find_nodes(self, ops, spectext, boxkinds=None):
loop = self.parse(ops, boxkinds=boxkinds)
perfect_specialization_finder = PerfectSpecializationFinder()
- perfect_specialization_finder.find_nodes(loop)
- assert self.assert_specnodes(perfect_specialization_finder.specnodes,
- spectext)
+ perfect_specialization_finder.find_nodes_loop(loop)
+ self.check_specnodes(perfect_specialization_finder.specnodes, spectext)
return (loop.getboxes(), perfect_specialization_finder.getnode)
def test_find_nodes_simple(self):
@@ -481,6 +485,35 @@
nextdescr=Virtual(node_vtable,
nextdescr=Virtual(node_vtable)))''')
+ # ------------------------------
+ # Bridge tests
+
+ def find_bridge(self, ops, inputspectext, outputspectext, boxkinds=None,
+ mismatch=False):
+ inputspecnodes = self.unpack_specnodes(inputspectext)
+ outputspecnodes = self.unpack_specnodes(outputspectext)
+ bridge = self.parse(ops, boxkinds=boxkinds)
+ bridge_specialization_finder = BridgeSpecializationFinder()
+ bridge_specialization_finder.setup_bridge_input_nodes(inputspecnodes,
+ bridge.inputargs)
+ bridge_specialization_finder.find_nodes(bridge.operations)
+ matches = bridge_specialization_finder.bridge_matches(
+ bridge.operations[-1],
+ outputspecnodes)
+ if mismatch:
+ assert not matches
+ else:
+ assert matches
+
+ def test_bridge_simple(self):
+ ops = """
+ [i0]
+ i1 = int_add(i0, 1)
+ jump(i1)
+ """
+ self.find_bridge(ops, 'Not', 'Not')
+ self.find_bridge(ops, 'Not', 'Virtual(node_vtable)', mismatch=True)
+
class TestLLtype(BaseTestOptimize, LLtypeMixin):
pass
More information about the Pypy-commit
mailing list