[pypy-svn] r65660 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
antocuni at codespeak.net
antocuni at codespeak.net
Mon Jun 8 15:39:34 CEST 2009
Author: antocuni
Date: Mon Jun 8 15:39:28 2009
New Revision: 65660
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py
- copied, changed from r65653, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
implement last step of perfect specialization.
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 15:39:28 2009
@@ -2,7 +2,7 @@
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, sort_descrs
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
NotSpecNode, FixedClassSpecNode
@@ -116,6 +116,29 @@
return specnode
return NotSpecNode()
+ def newinputargs(self):
+ if self.loop.inputargs is not None:
+ # closing a loop
+ assert len(self.loop.inputargs) == len(self.specnodes)
+ for i in range(len(self.specnodes)):
+ box = self.loop.inputargs[i]
+ self.specnodes[i].mutate_nodes(self.nodes[box])
+ return self.expanded_version_of(self.loop.inputargs)
+ else:
+ # making a bridge
+ return None
+
+ def expanded_version_of(self, boxlist):
+ newboxlist = []
+ assert len(boxlist) == len(self.specnodes)
+ for i in range(len(boxlist)):
+ box = boxlist[i]
+ specnode = self.specnodes[i]
+ specnode.expand_boxlist(self.nodes[box], newboxlist)
+ return newboxlist
+
+
+
class LoopOptimizer(object):
def __init__(self, optlist):
@@ -147,6 +170,8 @@
return val
def setval(self, box):
+ if box is None:
+ return
assert box not in self.values
assert not isinstance(box, Const)
self.values[box] = self.newval(box)
@@ -154,12 +179,17 @@
def optimize_loop(self, loop):
self._init(loop)
self.spec.find_nodes()
- self.optimize_operations()
+ self.spec.intersect_input_and_output()
+ newinputargs = self.spec.newinputargs()
+ newoperations = self.optimize_operations(newinputargs)
- def optimize_operations(self):
- for box in self.loop.inputargs:
- self.setval(box) # startbox=True)
+ self.loop.specnodes = self.spec.specnodes
+ self.loop.inputargs = newinputargs
+ self.loop.operations = newoperations
+ def optimize_operations(self, newinputargs):
+ for box in newinputargs:
+ self.setval(box) # startbox=True)
newoperations = []
for op in self.loop.operations:
newop = op
@@ -171,8 +201,8 @@
if newop is not None:
self.setval(newop.result)
newoperations.append(newop)
- print "Length of the loop:", len(newoperations)
- self.loop.operations = newoperations
+ #print "Length of the loop:", len(newoperations)
+ return newoperations
def new_arguments(self, op):
newboxes = []
@@ -274,7 +304,7 @@
if func:
func(self, spec, op)
- def interesect_nodes(self, a, b, nodes):
+ def intersect_nodes(self, spec, a, b, nodes):
return None
@@ -318,6 +348,7 @@
class OptimizeVirtuals(AbstractOptimization):
def init_node(self, node):
+ node.virtual = False
node.known_class = None
node.origfields = r_dict(av_eq, av_hash)
node.curfields = r_dict(av_eq, av_hash)
@@ -394,6 +425,51 @@
## b.cursize)
return VirtualInstanceSpecNode(known_class_box, fields)
+ # ---------------------------------------
+
+ def jump(self, opt, op):
+ args = opt.spec.expanded_version_of(op.args)
+ for arg in args:
+ if arg in opt.spec.nodes:
+ assert not opt.spec.nodes[arg].virtual
+ #self.cleanup_field_caches(newoperations)
+ op = op.clone()
+ op.args = args
+ return op
+
+ def guard_class(self, opt, op):
+ node = opt.spec.getnode(op.args[0])
+ if node.known_class is not None:
+ assert op.args[1].equals(node.known_class.source)
+ return None
+ return op
+
+ def new_with_vtable(self, opt, op):
+ node = opt.spec.getnode(op.result)
+ if not node.escaped:
+ node.virtual = True
+ assert node.known_class is not None
+ return None
+ return op
+
+ def getfield_gc(self, opt, op):
+ node = opt.spec.getnode(op.args[0])
+ descr = op.descr
+ assert isinstance(descr, AbstractValue)
+ if node.virtual:
+ assert descr in node.curfields
+ return None
+ return op
+
+ def setfield_gc(self, opt, op):
+ node = opt.spec.getnode(op.args[0])
+ valuenode = opt.spec.getnode(op.args[1])
+ descr = op.descr
+ if node.virtual:
+ node.curfields[descr] = valuenode
+ return None
+ return op
+
# -------------------------------------------------------------------
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py (from r65653, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py Mon Jun 8 15:39:28 2009
@@ -57,15 +57,15 @@
class FixedClassSpecNode(SpecNode):
def __init__(self, known_class):
- self.known_class = known_class
+ self.known_class = known_class.constbox()
def mutate_nodes(self, instnode):
- from pypy.jit.metainterp.optimize import InstanceNode
+ from pypy.jit.metainterp.optimize3 import InstanceNode
- if instnode.cls is None:
- instnode.cls = InstanceNode(self.known_class, const=True)
+ if instnode.known_class is None:
+ instnode.known_class = InstanceNode(self.known_class)
else:
- assert instnode.cls.source.equals(self.known_class)
+ assert instnode.known_class.source.equals(self.known_class)
def equals(self, other):
if type(other) is not FixedClassSpecNode:
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 15:39:28 2009
@@ -11,7 +11,7 @@
from pypy.jit.metainterp.optimize3 import AbstractOptimization
from pypy.jit.metainterp.optimize3 import optimize_loop, LoopOptimizer,\
LoopSpecializer, OptimizeGuards, OptimizeVirtuals
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
NotSpecNode
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
from pypy.jit.metainterp.test.oparser import parse
@@ -123,8 +123,12 @@
ops = """
[]
i1 = %s(3, 2)
+ jump()
""" % op.lower()
- expected = "[]"
+ expected = """
+ []
+ jump()
+ """
self.assert_equal(self.optimize(ops), expected)
def test_constfold_guard(self):
@@ -133,9 +137,11 @@
i0 = int_add(0, 0)
guard_value(i0, 0)
fail(i0)
+ jump()
"""
expected = """
[]
+ jump()
"""
loop = self.optimize(ops, [])
self.assert_equal(loop, expected)
@@ -147,11 +153,13 @@
fail()
guard_class(p0, ConstClass(node_vtable))
fail()
+ jump(p0)
"""
expected = """
[p0]
guard_class(p0, ConstClass(node_vtable))
fail()
+ jump(p0)
"""
loop = self.optimize(ops, [OptimizeGuards()])
self.assert_equal(loop, expected)
@@ -166,11 +174,13 @@
guard_value(i1, 1)
fail()
i2 = int_add(i1, 2)
+ jump(i0)
"""
expected = """
[i0]
guard_value(i0, 0)
fail()
+ jump(0)
"""
loop = self.parse(ops)
# cheat
@@ -241,7 +251,17 @@
assert spec_n.fields[0][0] == self.valuedescr
assert isinstance(spec_n.fields[0][1], NotSpecNode)
-
+ def test_virtual_simple_optimize_loop(self):
+ loop = self._get_virtual_simple_loop()
+ opt = LoopOptimizer([OptimizeVirtuals()])
+ opt.optimize_loop(loop)
+ expected = """
+ [i0, i1]
+ i2 = int_sub(i1, 1)
+ i3 = int_add(i0, i1)
+ jump(i3, i2)
+ """
+ self.assert_equal(loop, expected)
class TestLLtype(LLtypeMixin, BaseTestOptimize3):
More information about the Pypy-commit
mailing list