[pypy-svn] r65659 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
antocuni at codespeak.net
antocuni at codespeak.net
Mon Jun 8 12:16:11 CEST 2009
Author: antocuni
Date: Mon Jun 8 12:16:06 2009
New Revision: 65659
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
a bit of refactoring, and a new test:
- remove TrackClass and put its contents again into OptimizeVirtuals and
OptimizeGuards: the reason is that node.known_class is really needed by
OptimizeVirtuals, so it makes more sense to just put the code there
- add a new hook for the optimizations to do the intersection between nodes.
So far, only OptimizeVirtuals implements it, but doing a subset of what
the original optimize.InstanceNode.intersect does
- add test_virtual_simple_intersect_input_and_output, and implement the
corresponding LoopSpecializer method to make the test passing
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Mon Jun 8 12:16:06 2009
@@ -1,9 +1,11 @@
from pypy.rlib.objectmodel import r_dict
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import Const, Box, AbstractValue
-from pypy.jit.metainterp.optimize import av_eq, av_hash
-
+from pypy.jit.metainterp.optimize import av_eq, av_hash, sort_descrs
+from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+ NotSpecNode, FixedClassSpecNode
+
class InstanceNode(object):
def __init__(self, source, escaped=True):
self.source = source
@@ -16,6 +18,7 @@
#if self.virtual: flags += 'v'
#if self.virtualized: flags += 'V'
return "<InstanceNode %s (%s)>" % (self.source, flags)
+
class InstanceValue(object):
@@ -90,6 +93,28 @@
for arg in op.suboperations[0].args:
self.getnode(arg)
+ def recursively_find_escaping_values(self):
+ pass # for now
+
+ def intersect_input_and_output(self):
+ # Step (3)
+ self.recursively_find_escaping_values()
+ jump = self.loop.operations[-1]
+ assert jump.opnum == rop.JUMP
+ specnodes = []
+ for i in range(len(self.loop.inputargs)):
+ enternode = self.nodes[self.loop.inputargs[i]]
+ leavenode = self.getnode(jump.args[i])
+ #specnodes.append(enternode.intersect(leavenode, self.nodes))
+ specnodes.append(self.intersect_nodes(enternode, leavenode, self.nodes))
+ self.specnodes = specnodes
+
+ def intersect_nodes(self, a, b, nodes):
+ for opt in self.optlist:
+ specnode = opt.intersect_nodes(self, a, b, nodes)
+ if specnode is not None:
+ return specnode
+ return NotSpecNode()
class LoopOptimizer(object):
@@ -249,6 +274,9 @@
if func:
func(self, spec, op)
+ def interesect_nodes(self, a, b, nodes):
+ return None
+
# hooks for LoopOptimizer
# -------------------------
@@ -264,23 +292,7 @@
return op
-class TrackClass(AbstractOptimization):
-
- def init_node(self, node):
- node.known_class = None
-
- def find_nodes_new_with_vtable(self, spec, op):
- box = op.result
- node = spec.newnode(box, escaped=False)
- node.known_class = spec.newnode(op.args[0])
- spec.nodes[box] = node
-
- def find_nodes_guard_class(self, spec, op):
- node = spec.getnode(op.args[0])
- if node.known_class is None:
- node.known_class = spec.newnode(op.args[1])
-
- # -----------------------------
+class OptimizeGuards(AbstractOptimization):
def init_value(self, val):
val.cls = None
@@ -293,9 +305,6 @@
val.cls = opt.newval(op.args[1].constbox())
return op
-
-class OptimizeGuards(AbstractOptimization):
-
def guard_value(self, opt, op):
val = opt.getval(op.args[0])
assert isinstance(op.args[1], Const)
@@ -309,9 +318,21 @@
class OptimizeVirtuals(AbstractOptimization):
def init_node(self, node):
+ node.known_class = None
node.origfields = r_dict(av_eq, av_hash)
node.curfields = r_dict(av_eq, av_hash)
+ def find_nodes_new_with_vtable(self, spec, op):
+ box = op.result
+ node = spec.newnode(box, escaped=False)
+ node.known_class = spec.newnode(op.args[0])
+ spec.nodes[box] = node
+
+ def find_nodes_guard_class(self, spec, op):
+ node = spec.getnode(op.args[0])
+ if node.known_class is None:
+ node.known_class = spec.newnode(op.args[1])
+
def find_nodes_setfield_gc(self, spec, op):
instnode = spec.getnode(op.args[0])
fielddescr = op.descr
@@ -337,6 +358,42 @@
instnode.origfields[fielddescr] = fieldnode
spec.nodes[resbox] = fieldnode
+ def intersect_nodes(self, spec, a, b, nodes):
+ if not b.known_class:
+ return NotSpecNode()
+ if a.known_class:
+ if not a.known_class.source.equals(b.known_class.source):
+ #raise CancelInefficientLoop
+ return NotSpecNode()
+ known_class_box = a.known_class.source
+ else:
+ known_class_box = b.known_class.source
+ if b.escaped:
+ if a.known_class is None:
+ return NotSpecNode()
+## if isinstance(known_class_box, FixedList):
+## return NotSpecNode()
+ return FixedClassSpecNode(known_class_box)
+
+ assert a is not b
+ fields = []
+ d = b.curfields
+ lst = d.keys()
+ sort_descrs(lst)
+ for ofs in lst:
+ node = d[ofs]
+ if ofs not in a.origfields:
+ box = node.source.clonebox()
+ a.origfields[ofs] = InstanceNode(box, escaped=False)
+ a.origfields[ofs].known_class = node.known_class
+ nodes[box] = a.origfields[ofs]
+ specnode = spec.intersect_nodes(a.origfields[ofs], node, nodes)
+ fields.append((ofs, specnode))
+## if isinstance(known_class_box, FixedList):
+## return VirtualFixedListSpecNode(known_class_box, fields,
+## b.cursize)
+ return VirtualInstanceSpecNode(known_class_box, fields)
+
# -------------------------------------------------------------------
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Mon Jun 8 12:16:06 2009
@@ -10,7 +10,9 @@
from pypy.jit.metainterp.optimize3 import AbstractOptimization
from pypy.jit.metainterp.optimize3 import optimize_loop, LoopOptimizer,\
- LoopSpecializer, OptimizeGuards, OptimizeVirtuals, TrackClass
+ LoopSpecializer, OptimizeGuards, OptimizeVirtuals
+from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+ NotSpecNode
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
from pypy.jit.metainterp.test.oparser import parse
@@ -151,7 +153,7 @@
guard_class(p0, ConstClass(node_vtable))
fail()
"""
- loop = self.optimize(ops, [TrackClass()])
+ loop = self.optimize(ops, [OptimizeGuards()])
self.assert_equal(loop, expected)
@@ -203,7 +205,7 @@
def test_virtual_simple_find_nodes(self):
loop = self._get_virtual_simple_loop()
- spec = LoopSpecializer([TrackClass(), OptimizeVirtuals()])
+ spec = LoopSpecializer([OptimizeVirtuals()])
spec._init(loop)
spec.find_nodes()
@@ -224,6 +226,21 @@
assert len(spec.nodes[p1].origfields) == 0
assert spec.nodes[p1].curfields[self.valuedescr] is spec.nodes[i2]
+ def test_virtual_simple_intersect_input_and_output(self):
+ loop = self._get_virtual_simple_loop()
+ spec = LoopSpecializer([OptimizeVirtuals()])
+ spec._init(loop)
+ spec.find_nodes()
+ spec.intersect_input_and_output()
+
+ assert len(spec.specnodes) == 2
+ spec_sum, spec_n = spec.specnodes
+ assert isinstance(spec_sum, NotSpecNode)
+ assert isinstance(spec_n, VirtualInstanceSpecNode)
+ assert spec_n.known_class.value == self.node_vtable_adr
+ assert spec_n.fields[0][0] == self.valuedescr
+ assert isinstance(spec_n.fields[0][1], NotSpecNode)
+
More information about the Pypy-commit
mailing list