[pypy-svn] r66417 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Jul 19 19:30:51 CEST 2009
Author: arigo
Date: Sun Jul 19 19:30:51 2009
New Revision: 66417
Modified:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Progress. Implement GUARD_CLASS and replace the _consts dict
with an _equals mapping.
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 Sun Jul 19 19:30:51 2009
@@ -17,43 +17,57 @@
class Optimizer(object):
def __init__(self):
- # set of Boxes; the value is not stored in the dict, but can
- # be accessed as the Box.getint() or get_().
- self._consts = {}
+ self._equals = {} # mapping Box -> Box-or-Const
+ self._known_classes = {} # mapping Box -> ConstClass
- def is_constant(self, box):
- return isinstance(box, Const) or box in self._consts
+ def deref(self, box):
+ while box in self._equals:
+ # follow the chain: box -> box2 -> box3 -> ...
+ box2 = self._equals[box]
+ if box2 not in self._equals:
+ return box2
+ # compress the mapping one step (rare case)
+ box3 = self._equals[box2]
+ self._equals[box] = box3
+ box = box3
+ return box
def make_constant(self, box):
assert isinstance(box, Box)
- self._consts[box] = box.constbox()
+ assert box not in self._equals
+ self._equals[box] = box.constbox()
- def rename_argument(self, box):
- return self._consts.get(box, box)
+ def has_constant_class(self, box):
+ return isinstance(box, Const) or box in self._known_classes
+
+ def make_constant_class(self, box, clsbox):
+ assert isinstance(box, Box)
+ assert isinstance(clsbox, Const)
+ self._known_classes[box] = clsbox
# ----------
def optimize(self, loop):
self.newoperations = []
for op in loop.operations:
- opnum = op.opnum
+ op2 = op.clone()
+ op2.args = [self.deref(box) for box in op.args]
+ opnum = op2.opnum
for value, func in optimize_ops:
if opnum == value:
- func(self, op)
+ func(self, op2)
break
else:
- self.optimize_default(op)
+ self.optimize_default(op2)
loop.operations = self.newoperations
def emit_operation(self, op):
- op2 = op.clone()
- op2.args = [self.rename_argument(box) for box in op.args]
- self.newoperations.append(op2)
+ self.newoperations.append(op)
def optimize_default(self, op):
if op.is_always_pure():
for box in op.args:
- if not self.is_constant(box):
+ if not isinstance(box, Const):
break
else:
# all constant arguments: constant-fold away
@@ -63,23 +77,31 @@
self.emit_operation(op)
def optimize_GUARD_VALUE(self, op):
- if self.is_constant(op.args[0]):
- assert isinstance(op.args[1], Const)
- assert self.rename_argument(op.args[0]).get_() == op.args[1].get_()
- else:
+ assert isinstance(op.args[1], Const)
+ assert op.args[0].get_() == op.args[1].get_()
+ if not isinstance(op.args[0], Const):
self.emit_operation(op)
+ self.make_constant(op.args[0])
def optimize_GUARD_TRUE(self, op):
- if self.is_constant(op.args[0]):
- assert self.rename_argument(op.args[0]).getint()
- else:
+ assert op.args[0].getint()
+ if not isinstance(op.args[0], Const):
self.emit_operation(op)
+ self.make_constant(op.args[0])
def optimize_GUARD_FALSE(self, op):
- if self.is_constant(op.args[0]):
- assert not self.rename_argument(op.args[0]).getint()
- else:
+ assert not op.args[0].getint()
+ if not isinstance(op.args[0], Const):
+ self.emit_operation(op)
+ self.make_constant(op.args[0])
+
+ def optimize_GUARD_CLASS(self, op):
+ instbox = op.args[0]
+ clsbox = op.args[1]
+ # XXX should probably assert that the class is right
+ if not self.has_constant_class(instbox):
self.emit_operation(op)
+ self.make_constant_class(instbox, clsbox)
optimize_ops = _findall(Optimizer, 'optimize_')
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 Sun Jul 19 19:30:51 2009
@@ -3,6 +3,7 @@
OOtypeMixin,
BaseTest)
from pypy.jit.metainterp.optimizeopt import optimize
+from pypy.jit.metainterp.resoperation import rop, opname
from pypy.jit.metainterp.test.oparser import parse
# ____________________________________________________________
@@ -67,7 +68,7 @@
i0 = int_sub(i, 1)
guard_value(i0, 0)
fail(i0)
- jump(i0)
+ jump(i)
"""
self.optimize(ops, 'Not', ops)
@@ -91,6 +92,61 @@
"""
self.optimize(ops, '', expected, i0=5, i1=1, i2=0)
+ def test_constfold_all(self):
+ for op in range(rop.INT_ADD, rop.BOOL_NOT+1):
+ try:
+ op = opname[op]
+ except KeyError:
+ continue
+ ops = """
+ []
+ i1 = %s(3, 2)
+ jump()
+ """ % op.lower()
+ expected = """
+ []
+ jump()
+ """
+ self.optimize(ops, '', expected)
+
+ # ----------
+
+ def test_remove_guard_class(self):
+ ops = """
+ [p0]
+ guard_class(p0, ConstClass(node_vtable))
+ fail()
+ guard_class(p0, ConstClass(node_vtable))
+ fail()
+ jump(p0)
+ """
+ expected = """
+ [p0]
+ guard_class(p0, ConstClass(node_vtable))
+ fail()
+ jump(p0)
+ """
+ self.optimize(ops, 'Not', expected)
+
+ def test_remove_consecutive_guard_value_constfold(self):
+ ops = """
+ [i0]
+ guard_value(i0, 0)
+ fail()
+ i1 = int_add(i0, 1)
+ guard_value(i1, 1)
+ fail()
+ i2 = int_add(i1, 2)
+ jump(i2)
+ """
+ expected = """
+ [i0]
+ guard_value(i0, 0)
+ fail()
+ jump(3)
+ """
+ self.optimize(ops, 'Not', expected, i0=0, i1=1, i2=3)
+
class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin):
pass
More information about the Pypy-commit
mailing list