[pypy-svn] r66498 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Jul 22 09:36:58 CEST 2009
Author: arigo
Date: Wed Jul 22 09:36:56 2009
New Revision: 66498
Modified:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Start handling the fail() operations attached to guards.
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py Wed Jul 22 09:36:56 2009
@@ -3,7 +3,7 @@
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.specnode import SpecNode
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.optimizeutil import av_newdict, _findall
+from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs
from pypy.rlib.objectmodel import we_are_translated
@@ -36,6 +36,10 @@
def force_box(self):
return self.box
+ def get_args_for_fail(self, list):
+ if not self.is_constant():
+ list.append(self.box)
+
def is_constant(self):
return self.level == LEVEL_CONSTANT
@@ -114,6 +118,15 @@
newoperations.append(op)
return self.box
+ def get_args_for_fail(self, list):
+ if self.box is not None:
+ InstanceValue.get_args_for_fail(self, list)
+ else:
+ lst = self._fields.keys()
+ sort_descrs(lst)
+ for ofs in lst:
+ self._fields[ofs].get_args_for_fail(list)
+
class __extend__(SpecNode):
def setup_virtual_node(self, optimizer, box, newinputargs):
@@ -217,6 +230,7 @@
self.loop.operations = self.newoperations
def emit_operation(self, op, must_clone=True):
+ op1 = op
for i in range(len(op.args)):
arg = op.args[i]
if arg in self.values:
@@ -226,9 +240,32 @@
op = op.clone()
must_clone = False
op.args[i] = box
- self.newoperations.append(op)
- if op.can_raise():
+ if op.is_guard():
+ self.clone_guard(op, op1)
+ elif op.can_raise():
self.exception_might_have_happened = True
+ self.newoperations.append(op)
+
+ def clone_guard(self, op2, op1):
+ assert len(op1.suboperations) == 1
+ op_fail = op1.suboperations[0]
+ assert op_fail.opnum == rop.FAIL
+ #
+ newboxes = []
+ for box in op_fail.args:
+ try:
+ value = self.values[box]
+ except KeyError:
+ newboxes.append(box)
+ else:
+ value.get_args_for_fail(newboxes)
+ # NB. we mutate op_fail in-place above. That's bad. Hopefully
+ # it does not really matter because no-one is going to look again
+ # at its unoptimized version. We cannot really clone it because of
+ # how the rest works (e.g. it is returned by cpu.execute_operations()).
+ op_fail.args = newboxes
+ op2.suboperations = op1.suboperations
+ op1.optimized = op2
def optimize_default(self, op):
if op.is_always_pure():
@@ -250,9 +287,10 @@
for i in range(len(specnodes)):
value = self.getvalue(op.args[i])
specnodes[i].teardown_virtual_node(self, value, exitargs)
- op = op.clone()
- op.args = exitargs
- self.emit_operation(op, must_clone=False)
+ op2 = op.clone()
+ op2.args = exitargs
+ op2.jump_target = op.jump_target
+ self.emit_operation(op2, must_clone=False)
def optimize_guard(self, op):
value = self.getvalue(op.args[0])
@@ -263,14 +301,15 @@
def optimize_GUARD_VALUE(self, op):
assert isinstance(op.args[1], Const)
+ assert op.args[0].getint() == op.args[1].getint()
self.optimize_guard(op)
def optimize_GUARD_TRUE(self, op):
- assert op.args[0].getint()
+ assert op.args[0].getint() == 1
self.optimize_guard(op)
def optimize_GUARD_FALSE(self, op):
- assert not op.args[0].getint()
+ assert op.args[0].getint() == 0
self.optimize_guard(op)
def optimize_GUARD_CLASS(self, op):
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py Wed Jul 22 09:36:56 2009
@@ -34,9 +34,7 @@
self.descr = descr
def clone(self):
- res = ResOperation(self.opnum, self.args, self.result, self.descr)
- res.jump_target = self.jump_target
- return res
+ return ResOperation(self.opnum, self.args, self.result, self.descr)
def __repr__(self):
return self.repr()
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py Wed Jul 22 09:36:56 2009
@@ -480,7 +480,7 @@
# the 'expected' is sub-optimal, but it should be done by another later
# optimization step. See test_find_nodes_default_field() for why.
self.optimize_loop(ops, 'Virtual(node_vtable, valuedescr=Not)',
- expected)
+ expected, i0=0)
def test_virtual_3(self):
ops = """
@@ -570,6 +570,27 @@
self.optimize_loop(ops, 'Not', expected, i1=5,
boxkinds={'myptr': self.nodebox.value})
+ def test_expand_fail_arguments(self):
+ ops = """
+ [i1, i2, i3, p3]
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ setfield_gc(p1, 1, descr=valuedescr)
+ setfield_gc(p1, p2, descr=nextdescr)
+ setfield_gc(p2, i2, descr=valuedescr)
+ setfield_gc(p2, p3, descr=nextdescr)
+ guard_true(i1)
+ fail(p1, i3)
+ jump(i2, i1, i3, p3)
+ """
+ expected = """
+ [i1, i2, i3, p3]
+ guard_true(i1)
+ fail(i2, p3, i3)
+ jump(i2, 1, i3, p3)
+ """
+ self.optimize_loop(ops, 'Not, Not, Not, Not', expected, i1=1)
+
class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin):
pass
More information about the Pypy-commit
mailing list