[pypy-svn] r65832 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test
antocuni at codespeak.net
antocuni at codespeak.net
Fri Jun 19 18:06:32 CEST 2009
Author: antocuni
Date: Fri Jun 19 18:06:31 2009
New Revision: 65832
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize3.py
Log:
port one test from test_optimize.py. Add support for rebuilding virtuals that
escape from failing guards
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize3.py Fri Jun 19 18:06:31 2009
@@ -1,6 +1,7 @@
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.history import Const, Box, AbstractValue,\
+ AbstractDescr, ConstObj
from pypy.jit.metainterp.optimize import av_eq, av_hash, sort_descrs
from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
NotSpecNode, FixedClassSpecNode
@@ -150,11 +151,12 @@
self.values = None # box --> InstanceValue
- def _init(self, loop):
+ def _init(self, loop, cpu):
self.spec._init(loop)
self.fixedops = {}
self.values = {}
self.loop = loop
+ self.cpu = cpu
def newval(self, *args, **kwds): # XXX RPython
val = InstanceValue(*args, **kwds)
@@ -178,8 +180,8 @@
assert not isinstance(box, Const)
self.values[box] = self.newval(box)
- def optimize_loop(self, loop):
- self._init(loop)
+ def optimize_loop(self, loop, cpu):
+ self._init(loop, cpu)
self.spec.find_nodes()
self.spec.intersect_input_and_output()
newinputargs = self.spec.newinputargs()
@@ -254,14 +256,36 @@
break
else:
return None
- op.args = self.new_arguments(op)
assert len(op.suboperations) == 1
op_fail = op.suboperations[0]
- op_fail.args = self.new_arguments(op_fail)
- # modification in place. Reason for this is explained in mirror
- # in optimize.py
- op.suboperations = [op_fail]
- return op
+ assert op_fail.opnum == rop.FAIL
+ oplist = self.rebuild_ops(op_fail)
+ op_fail.args = self.new_arguments(op_fail) # modify in place, see optimize.py
+ newop = op.clone()
+ newop.args = self.new_arguments(newop)
+ newop.suboperations = oplist + [op_fail]
+
+ return newop
+
+ def rebuild_ops(self, op):
+ oplist = []
+ memo = {}
+ for box in op.args:
+ if isinstance(box, Const) or box not in self.spec.nodes:
+ continue
+ node = self.spec.getnode(box)
+ self.rebuild_box(oplist, memo, node, box)
+ return oplist
+
+ def rebuild_box(self, oplist, memo, node, box):
+ if not isinstance(box, Box):
+ return box
+ if box in memo:
+ return box
+ memo[box] = None
+ for opt in self.optlist:
+ opt.rebuild_box(self, oplist, memo, node, box)
+ return box
# -------------------------------------------------------------------
@@ -328,6 +352,9 @@
def handle_default_op(self, spec, op):
return op
+ def rebuild_box(self, oplist, node, box):
+ pass
+
class OptimizeGuards(AbstractOptimization):
@@ -475,6 +502,47 @@
# ---------------------------------------
+ def _new_obj(self, cpu, clsbox, resbox):
+## if isinstance(clsbox, FixedList):
+## ad = clsbox.arraydescr
+## sizebox = ConstInt(node.cursize)
+## op = ResOperation(rop.NEW_ARRAY, [sizebox], box,
+## descr=ad)
+ if cpu.is_oo and isinstance(clsbox, ConstObj):
+ # it's probably a ootype new
+ cls = clsbox.getobj()
+ typedescr = cpu.class_sizes[cls]
+ return ResOperation(rop.NEW_WITH_VTABLE, [clsbox], resbox,
+ descr=typedescr)
+ else:
+ assert not cpu.is_oo
+ vtable = clsbox.getint()
+ if cpu.translate_support_code:
+ vtable_addr = cpu.cast_int_to_adr(vtable)
+ size = cpu.class_sizes[vtable_addr]
+ else:
+ size = cpu.class_sizes[vtable]
+ return ResOperation(rop.NEW_WITH_VTABLE, [clsbox], resbox,
+ descr=size)
+
+ def rebuild_box(self, opt, oplist, memo, node, box):
+ if not node.virtual:
+ return
+ clsbox = node.known_class.source
+ oplist.append(self._new_obj(opt.cpu, clsbox, box))
+ opt.setval(box) # make sure that the value for this box exists
+ for descr, node in node.curfields.items():
+ fieldbox = opt.rebuild_box(oplist, memo, node, node.source)
+## if isinstance(clsbox, FixedList):
+## op = ResOperation(rop.SETARRAYITEM_GC,
+## [box, descr, fieldbox],
+## None, descr=clsbox.arraydescr)
+## else:
+ assert isinstance(descr, AbstractDescr)
+ op = ResOperation(rop.SETFIELD_GC, [box, fieldbox],
+ None, descr=descr)
+ oplist.append(op)
+
def jump(self, opt, op):
args = opt.spec.expanded_version_of(op.args)
for arg in args:
@@ -534,7 +602,7 @@
assert len(old_loops) == 1
return old_loops[0]
else:
- opt.optimize_loop(loop)
+ opt.optimize_loop(loop, cpu)
return None
def optimize_bridge(options, old_loops, loop, cpu=None, spec=None):
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize3.py Fri Jun 19 18:06:31 2009
@@ -63,6 +63,8 @@
nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodesize = cpu.sizeof(NODE)
valuedescr = cpu.fielddescrof(NODE, 'value')
+
+ cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE)}
namespace = locals()
class OOtypeMixin(object):
@@ -83,6 +85,7 @@
valuedescr = cpu.fielddescrof(NODE, 'value')
nodesize = cpu.typedescrof(NODE)
+ cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE)}
namespace = locals()
class BaseTestOptimize3(object):
@@ -228,7 +231,7 @@
def test_optimize_loop(self):
loop = self.getloop()
opt = LoopOptimizer([OptimizeVirtuals()])
- opt.optimize_loop(loop)
+ opt.optimize_loop(loop, self.cpu)
self.check_optimize_loop(opt, loop)
@@ -402,6 +405,57 @@
self.assert_equal(loop, expected)
+class RebuildOps(BaseVirtualTest):
+
+ def getloop(self):
+ ops = """
+ [sum, n1]
+ guard_class(n1, ConstClass(node_vtable))
+ fail()
+ v = getfield_gc(n1, descr=valuedescr)
+ v2 = int_sub(v, 1)
+ sum2 = int_add(sum, v)
+ n2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ setfield_gc(n2, v2, descr=valuedescr)
+ guard_true(v2)
+ fail(sum2, n2)
+ jump(sum2, n2)
+ """
+ loop = self.parse(ops, boxkinds={'sum': BoxInt,
+ 'v': BoxInt,
+ 'n': BoxPtr})
+ loop.setvalues(sum = 0,
+ n1 = self.nodebox.value,
+ v = 20,
+ v2 = 19,
+ sum2 = 20,
+ n2 = self.nodebox2.value)
+ return loop
+
+ def test_find_nodes(self):
+ pass
+
+ def test_intersect_input_and_output(self):
+ pass
+
+ def check_optimize_loop(self, opt, loop):
+ expected = """
+ [sum, v]
+ v2 = int_sub(v, 1)
+ sum2 = int_add(sum, v)
+ guard_true(v2)
+ # XXX not checked
+ n2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ setfield_gc(n2, v2, descr=valuedescr)
+ fail(sum2, n2)
+ jump(sum2, v2)
+ """
+ self.assert_equal(loop, expected)
+ # XXX: it seems that guard_true.suboperations is not checked
+ # check it manually
+ assert loop.operations[-2].suboperations[0].opnum == rop.NEW_WITH_VTABLE
+ assert loop.operations[-2].suboperations[1].opnum == rop.SETFIELD_GC
+ assert loop.operations[-2].suboperations[2].opnum == rop.FAIL
def create_tests(ns):
for name, value in ns.items():
More information about the Pypy-commit
mailing list