[pypy-svn] r65363 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
antocuni at codespeak.net
antocuni at codespeak.net
Sat May 23 17:49:30 CEST 2009
Author: antocuni
Date: Sat May 23 17:49:29 2009
New Revision: 65363
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
- copied, changed from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
- copied, changed from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
yet another optimize*.py. The idea is that you can write a new class for each
optimization, and methods of the class will be called for each corresponding
operation.
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 17:49:29 2009
@@ -1,6 +1,3 @@
-
-""" Simplified optimize.py
-"""
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import Const, Box
@@ -27,6 +24,9 @@
loop = None
nodes = None
+ def __init__(self, optlist):
+ self.optlist = optlist
+
def getnode(self, box):
try:
return self.nodes[box]
@@ -75,74 +75,16 @@
newboxes.append(box)
return newboxes
- def optimize_guard(self, 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]
-
def optimize_operations(self):
newoperations = []
for op in self.loop.operations:
- if op.is_guard():
- if op.opnum == rop.GUARD_NONVIRTUALIZED:
- continue
- elif op.opnum == rop.GUARD_CLASS:
- node = self.getnode(op.args[0])
- if node.cls is not None:
- # assert that they're equal maybe
- continue
- node.cls = InstanceNode(op.args[1], const=True)
- elif op.opnum == rop.GUARD_VALUE:
- instnode = self.nodes[op.args[0]]
- assert isinstance(op.args[1], Const)
- if instnode.const:
- continue
- self.optimize_guard(op)
- instnode.const = True
- instnode.source = op.args[0].constbox()
- newoperations.append(op)
- continue
- self.optimize_guard(op)
- newoperations.append(op)
- continue
- elif op.opnum == rop.GETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = instnode.cleanfields.get(descr, None)
- if node is not None:
- self.nodes[op.result] = node
- continue
- else:
- instnode.cleanfields[descr] = self.getnode(op.result)
- elif op.opnum == rop.SETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = self.getnode(op.args[1])
- instnode.dirtyfields[descr] = node
- instnode.cleanfields[descr] = node
- l = self.field_caches.setdefault(descr, [])
- l.append((instnode, node))
- continue
- # default handler
- op = op.clone()
- op.args = self.new_arguments(op)
- if op.is_always_pure():
- for box in op.args:
- if isinstance(box, Box):
- break
- else:
- # all constant arguments: constant-fold away
- box = op.result
- assert box is not None
- instnode = InstanceNode(box.constbox(), const=True)
- self.nodes[box] = instnode
- continue
- elif not op.has_no_side_effect():
- self.clean_up_caches(newoperations)
- newoperations.append(op)
+ newop = op
+ for optimization in self.optlist:
+ newop = optimization.handle_op(self, newop)
+ if newop is None:
+ break
+ if newop is not None:
+ newoperations.append(newop)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
@@ -161,7 +103,77 @@
self.find_nodes()
self.optimize_operations()
-specializer = Specializer()
+# -------------------------------------------------------------------
+
+class AbstractOptimization(object):
+
+ def __init__(self):
+ 'NOT_RPYTHON'
+ operations = [None] * (rop._LAST+1)
+ for key, value in rop.__dict__.items():
+ if key.startswith('_'):
+ continue
+ methname = key.lower()
+ if hasattr(self, methname):
+ func = getattr(self, methname).im_func
+ else:
+ func = getattr(self, 'handle_default_op').im_func
+ operations[value] = func
+ self.operations = operations
+
+ def handle_op(self, spec, op):
+ func = self.operations[op.opnum]
+ return func(self, spec, op)
+
+ def handle_default_op(self, spec, op):
+ return op
+
+
+class OptimizeGuards(AbstractOptimization):
+
+ def optimize_guard(self, spec, op):
+ assert len(op.suboperations) == 1
+ op_fail = op.suboperations[0]
+ op_fail.args = spec.new_arguments(op_fail)
+ # modification in place. Reason for this is explained in mirror
+ # in optimize.py
+ op.suboperations = [op_fail]
+ return op
+
+ def guard_class(self, spec, op):
+ node = spec.getnode(op.args[0])
+ if node.cls is not None:
+ # assert that they're equal maybe
+ return
+ node.cls = InstanceNode(op.args[1], const=True)
+ return self.optimize_guard(spec, op)
+
+## def guard_value(self, spec, op):
+## instnode = spec.nodes[op.args[0]]
+## assert isinstance(op.args[1], Const)
+## if instnode.const:
+## return
+## self.optimize_guard(spec, op)
+## instnode.const = True
+## instnode.source = op.args[0].constbox()
+## return op
+
+## def guard_nonvirtualized(self, spec, op):
+## return
+
+## def handle_default_op(self, spec, op):
+## if op.is_guard():
+## return self.optimize_guard(op)
+## return op
+
+
+
+# -------------------------------------------------------------------
+
+OPTLIST = [
+ OptimizeGuards(),
+ ]
+specializer = Specializer(OPTLIST)
def optimize_loop(options, old_loops, loop, cpu=None):
if old_loops:
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Sat May 23 17:49:29 2009
@@ -8,9 +8,31 @@
ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.optimize2 import optimize_loop
+from pypy.jit.metainterp.optimize3 import AbstractOptimization
+from pypy.jit.metainterp.optimize3 import optimize_loop
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
+def test_AbstractOptimization():
+
+ class MyOpt(AbstractOptimization):
+ def int_add(self, spec, op):
+ return 'hello world', op
+
+ class MyOpt2(MyOpt):
+ def handle_default_op(self, spec, op):
+ return 'default op', op
+
+ myopt = MyOpt()
+ myopt2 = MyOpt2()
+ op = ResOperation(rop.INT_ADD, [], None)
+ assert myopt.handle_op(None, op) == ('hello world', op)
+ assert myopt2.handle_op(None, op) == ('hello world', op)
+
+ op = ResOperation(rop.INT_SUB, [], None)
+ assert myopt.handle_op(None, op) == op
+ assert myopt2.handle_op(None, op) == ('default op', op)
+
+
class LLtypeMixin(object):
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -42,7 +64,7 @@
-class BaseTestOptimize2(object):
+class BaseTestOptimize3(object):
@staticmethod
def newloop(inputargs, operations):
@@ -51,6 +73,7 @@
loop.operations = operations
return loop
+
def test_remove_guard_class(self):
ops = [
ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
@@ -63,6 +86,7 @@
assert len(loop.operations) == 1
def test_remove_consecutive_guard_value_constfold(self):
+ py.test.skip('in-progress')
n = BoxInt(0)
n1 = BoxInt(1)
n2 = BoxInt(3)
@@ -81,6 +105,7 @@
])
def test_remove_consecutive_getfields(self):
+ py.test.skip('in-progress')
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -97,6 +122,7 @@
])
def test_setfield_getfield_clean_cache(self):
+ py.test.skip('in-progress')
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -115,8 +141,8 @@
])
-class TestLLtype(LLtypeMixin, BaseTestOptimize2):
+class TestLLtype(LLtypeMixin, BaseTestOptimize3):
pass
-class TestOOtype(OOtypeMixin, BaseTestOptimize2):
+class TestOOtype(OOtypeMixin, BaseTestOptimize3):
pass
More information about the Pypy-commit
mailing list