[pypy-svn] r66275 - pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test
arigo at codespeak.net
arigo at codespeak.net
Thu Jul 16 10:32:29 CEST 2009
Author: arigo
Date: Thu Jul 16 10:32:28 2009
New Revision: 66275
Added:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py
- copied, changed from r66274, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize3.py
Log:
Rewrite the test copying test_optimize3.py.
Add some tests -- it's much easier now to just write a few
extra tests :-)
Copied: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py (from r66274, pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize3.py)
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py Thu Jul 16 10:32:28 2009
@@ -1,20 +1,17 @@
import py
+
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
-from pypy.jit.metainterp.history import ConstAddr, BoxPtr, TreeLoop,\
- ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
-
-from pypy.jit.metainterp.optimize3 import AbstractOptimization
-from pypy.jit.metainterp.optimize3 import optimize_loop, LoopOptimizer,\
- LoopSpecializer, OptimizeGuards, OptimizeVirtuals
-from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
- NotSpecNode, FixedClassSpecNode
+from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
+ Const, ConstAddr, TreeLoop, BoxObj)
+from pypy.jit.metainterp.optimize import perfect_specialization_finder
from pypy.jit.metainterp.test.oparser import parse
+# ____________________________________________________________
+
def equaloplists(oplist1, oplist2):
print '-'*20, 'Comparing lists', '-'*20
for op1, op2 in zip(oplist1, oplist2):
@@ -27,18 +24,15 @@
assert op1.opnum == op2.opnum
assert len(op1.args) == len(op2.args)
for x, y in zip(op1.args, op2.args):
- assert x == y # or y == x # for ANY object :-(
+ assert x == y
assert op1.result == op2.result
assert op1.descr == op2.descr
if op1.suboperations:
assert equaloplists(op1.suboperations, op2.suboperations)
assert len(oplist1) == len(oplist2)
print '-'*57
- #finally:
- # Box._extended_display = saved
return True
-
def test_equaloplists():
ops = """
[i0]
@@ -55,37 +49,7 @@
py.test.raises(AssertionError,
"equaloplists(loop1.operations, loop3.operations)")
-
-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
-
- def find_nodes_int_add(self, spec, op):
- op.found = 42
-
- 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)
- myopt.find_nodes_for_op(None, op)
- assert not hasattr(op, 'found')
- myopt2.find_nodes_for_op(None, op)
- assert op.found == 42
-
- op = ResOperation(rop.INT_SUB, [], None)
- assert myopt.handle_op(None, op) == op
- assert myopt2.handle_op(None, op) == ('default op', op)
- myopt2.find_nodes_for_op(None, op)
- assert not hasattr(op, 'found')
-
-
+# ____________________________________________________________
class LLtypeMixin(object):
type_system = 'lltype'
@@ -103,6 +67,7 @@
nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodesize = cpu.sizeof(NODE)
valuedescr = cpu.fielddescrof(NODE, 'value')
+ nextdescr = cpu.fielddescrof(NODE, 'next')
cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE)}
namespace = locals()
@@ -123,418 +88,108 @@
nodebox = BoxObj(ootype.cast_to_object(node))
nodebox2 = BoxObj(ootype.cast_to_object(node))
valuedescr = cpu.fielddescrof(NODE, 'value')
+ nextdescr = cpu.fielddescrof(NODE, 'next')
nodesize = cpu.typedescrof(NODE)
cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE)}
namespace = locals()
-class BaseTestOptimize3(object):
+# ____________________________________________________________
- @staticmethod
- def newloop(inputargs, operations):
- loop = TreeLoop("test")
- loop.inputargs = inputargs
- loop.operations = operations
- return loop
+class BaseTestOptimize(object):
def parse(self, s, boxkinds=None):
return parse(s, self.cpu, self.namespace,
type_system=self.type_system,
boxkinds=boxkinds)
- def optimize(self, lst, optlist=None):
- if not isinstance(lst, TreeLoop):
- loop = self.parse(lst)
- else:
- loop = lst
- if optlist is None:
- optlist = []
- optimize_loop(None, [], loop, self.cpu,
- opt=LoopOptimizer(optlist))
- return loop
-
def assert_equal(self, optimized, expected):
equaloplists(optimized.operations,
self.parse(expected).operations)
+ def find_nodes(self, ops, boxkinds=None):
+ loop = self.parse(ops, boxkinds=boxkinds)
+ perfect_specialization_finder.find_nodes(loop)
+ return loop.getboxes(), perfect_specialization_finder.getnode
-class CheckConstFold(BaseTestOptimize3):
-
- def test_constfold(self):
- for op in range(rop.INT_ADD, rop._COMPARISON_FIRST):
- try:
- op = opname[op]
- except KeyError:
- continue
- ops = """
- []
- i1 = %s(3, 2)
- jump()
- """ % op.lower()
- expected = """
- []
- jump()
- """
- self.assert_equal(self.optimize(ops), expected)
-
- def test_constfold_guard(self):
+ def test_find_nodes_simple(self):
ops = """
- []
- i0 = int_add(0, 0)
+ [i]
+ i0 = int_sub(i, 1)
guard_value(i0, 0)
fail(i0)
- jump()
- """
- expected = """
- []
- jump()
+ jump(i0)
"""
- loop = self.optimize(ops, [])
- self.assert_equal(loop, expected)
-
+ boxes, getnode = self.find_nodes(ops)
+ assert getnode(boxes.i) is not getnode(boxes.i0)
-class CheckOptimizeGuards(BaseTestOptimize3):
-
- def test_remove_guard_class(self):
+ def test_find_nodes_non_escape(self):
ops = """
[p0]
- guard_class(p0, ConstClass(node_vtable))
- fail()
- guard_class(p0, ConstClass(node_vtable))
- fail()
+ p1 = getfield_gc(p0, descr=nextdescr)
+ i0 = getfield_gc(p1, descr=valuedescr)
+ i1 = int_sub(i0, 1)
+ p2 = getfield_gc(p0, descr=nextdescr)
+ setfield_gc(p2, i1, descr=valuedescr)
jump(p0)
"""
- expected = """
+ boxes, getnode = self.find_nodes(ops)
+ assert not getnode(boxes.p0).escaped
+ assert not getnode(boxes.p1).escaped
+ assert not getnode(boxes.p2).escaped
+
+ def test_find_nodes_escape(self):
+ ops = """
[p0]
- guard_class(p0, ConstClass(node_vtable))
- fail()
+ p1 = getfield_gc(p0, descr=nextdescr)
+ p2 = getfield_gc(p1, descr=nextdescr)
+ i0 = getfield_gc(p2, descr=valuedescr)
+ i1 = int_sub(i0, 1)
+ escape(p1)
+ p3 = getfield_gc(p0, descr=nextdescr)
+ setfield_gc(p3, i1, descr=valuedescr)
+ p4 = getfield_gc(p1, descr=nextdescr)
+ setfield_gc(p4, i1, descr=valuedescr)
jump(p0)
"""
- loop = self.optimize(ops, [OptimizeGuards()])
- self.assert_equal(loop, expected)
-
+ boxes, getnode = self.find_nodes(ops)
+ assert not getnode(boxes.p0).escaped
+ assert getnode(boxes.p1).escaped
+ assert getnode(boxes.p2).escaped # forced by p1
+ assert getnode(boxes.p3).escaped # forced because p3 == p1
+ assert getnode(boxes.p4).escaped # forced by p1
- def test_remove_consecutive_guard_value_constfold(self):
+ def test_find_nodes_new(self):
ops = """
- [i0]
- guard_value(i0, 0)
- fail()
- i1 = int_add(i0, 1)
- guard_value(i1, 1)
- fail()
- i2 = int_add(i1, 2)
- jump(i0)
- """
- expected = """
- [i0]
- guard_value(i0, 0)
+ [sum, p1]
+ guard_class(p1, ConstClass(node_vtable))
fail()
- jump(0)
- """
- loop = self.parse(ops)
- loop.setvalues(i0 = 0, i1 = 1, i2 = 3)
- loop = self.optimize(loop, [OptimizeGuards()])
- self.assert_equal(loop, expected)
-
-
-class BaseVirtualTest(BaseTestOptimize3):
-
- def getloop(self):
- raise NotImplementedError
-
- def check_find_nodes(self, spec, loop):
- pass
-
- def check_intersect_input_and_output(self, spec, loop):
- pass
-
- def check_optimize_loop(self, opt, loop):
- pass
-
- def test_find_nodes(self):
- loop = self.getloop()
- spec = LoopSpecializer([OptimizeVirtuals()])
- spec._init(loop)
- spec.find_nodes()
- self.check_find_nodes(spec, loop)
-
- def test_intersect_input_and_output(self):
- loop = self.getloop()
- spec = LoopSpecializer([OptimizeVirtuals()])
- spec._init(loop)
- spec.find_nodes()
- spec.intersect_input_and_output()
- self.check_intersect_input_and_output(spec, loop)
-
- def test_optimize_loop(self):
- loop = self.getloop()
- opt = LoopOptimizer([OptimizeVirtuals()])
- opt.optimize_loop(loop, self.cpu)
- self.check_optimize_loop(opt, loop)
-
-
-class MallocRemoval(BaseVirtualTest):
-
- def getloop(self):
- ops = """
- [i0]
- p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
- setfield_gc(p0, i0, descr=valuedescr)
- i1 = getfield_gc(p0, descr=valuedescr)
- i2 = int_add(i1, 1)
- jump(i2)
- """
- loop = self.parse(ops)
- loop.setvalues(i0 = 40, i1 = 40, i2 = 41)
- return loop
-
- def test_find_nodes(self):
- pass
-
- def test_intersect_input_and_output(self):
- pass
-
- def check_optimize_loop(self, opt, loop):
- expected = """
- [i0]
- i2 = int_add(i0, 1)
- jump(i2)
- """
- self.assert_equal(loop, expected)
-
-
-class VirtualSimpleLoop(BaseVirtualTest):
-
- def getloop(self):
- ops = """
- [i0, p0]
- guard_class(p0, ConstClass(node_vtable))
- fail()
- i1 = getfield_gc(p0, descr=valuedescr)
+ i1 = getfield_gc(p1, descr=valuedescr)
i2 = int_sub(i1, 1)
- i3 = int_add(i0, i1)
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
- setfield_gc(p1, i2, descr=valuedescr)
- jump(i3, p1)
- """
- loop = self.parse(ops)
- loop.setvalues(i0 = 0,
- p0 = self.nodebox.value,
- i1 = 20,
- i2 = 19,
- i3 = 20,
- p1 = self.nodebox2.value)
- return loop
-
- def check_find_nodes(self, spec, loop):
- b = loop.getboxes()
- assert spec.nodes[b.i0] is not spec.nodes[b.i3]
- assert spec.nodes[b.p0] is not spec.nodes[b.p1]
- assert spec.nodes[b.p0].known_class.source.value == self.node_vtable_adr
- assert not spec.nodes[b.p0].escaped
- assert spec.nodes[b.p1].known_class.source.value == self.node_vtable_adr
- assert not spec.nodes[b.p1].escaped
-
- assert len(spec.nodes[b.p0].curfields) == 0
- assert spec.nodes[b.p0].origfields[self.valuedescr] is spec.nodes[b.i1]
- assert len(spec.nodes[b.p1].origfields) == 0
- assert spec.nodes[b.p1].curfields[self.valuedescr] is spec.nodes[b.i2]
-
- def check_intersect_input_and_output(self, spec, loop):
- assert len(spec.specnodes) == 2
- spec_sum, spec_n = spec.specnodes
- assert isinstance(spec_sum, NotSpecNode)
- assert isinstance(spec_n, VirtualInstanceSpecNode)
- assert spec_n.known_class.value == self.node_vtable_adr
- assert spec_n.fields[0][0] == self.valuedescr
- assert isinstance(spec_n.fields[0][1], NotSpecNode)
-
- def check_optimize_loop(self, opt, loop):
- expected = """
- [i0, i1]
- i2 = int_sub(i1, 1)
- i3 = int_add(i0, i1)
- jump(i3, i2)
- """
- self.assert_equal(loop, expected)
-
-
-class VirtualEscape1(BaseVirtualTest):
-
- def getloop(self):
- ops = """
- [sum, n1]
- guard_class(n1, ConstClass(node_vtable))
- fail()
- escape(n1)
- 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)
- escape(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 check_find_nodes(self, spec, loop):
- b = loop.getboxes()
- assert spec.nodes[b.n1].known_class.source.value == self.node_vtable_adr
- assert spec.nodes[b.n1].escaped
- assert spec.nodes[b.n2].known_class.source.value == self.node_vtable_adr
- assert spec.nodes[b.n2].escaped
-
- def check_intersect_input_and_output(self, spec, loop):
- assert len(spec.specnodes) == 2
- spec_sum, spec_n = spec.specnodes
- assert isinstance(spec_sum, NotSpecNode)
- assert type(spec_n) is FixedClassSpecNode
- assert spec_n.known_class.value == self.node_vtable_adr
-
- def check_optimize_loop(self, opt, loop):
- expected = """
- [sum, n1]
- escape(n1)
- 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)
- escape(n2)
- jump(sum2, n2)
- """
- self.assert_equal(loop, expected)
-
-
-class VirtualEscape2(BaseVirtualTest):
-
- def getloop(self):
- ops = """
- [sum, n1]
- guard_class(n1, ConstClass(node_vtable))
- fail()
- escape(n1)
- v = getfield_gc(n1, descr=valuedescr)
- v2 = int_sub(v, 1)
- sum2 = int_add(sum, v)
- escape(n1)
- n2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
- setfield_gc(n2, v2, descr=valuedescr)
- 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 check_find_nodes(self, spec, loop):
- b = loop.getboxes()
- assert spec.nodes[b.n1].known_class.source.value == self.node_vtable_adr
- assert spec.nodes[b.n1].escaped
- assert spec.nodes[b.n2].known_class.source.value == self.node_vtable_adr
-
- def check_intersect_input_and_output(self, spec, loop):
- b = loop.getboxes()
- assert spec.nodes[b.n2].escaped
- assert len(spec.specnodes) == 2
- spec_sum, spec_n = spec.specnodes
- assert isinstance(spec_sum, NotSpecNode)
- assert type(spec_n) is FixedClassSpecNode
- assert spec_n.known_class.value == self.node_vtable_adr
-
- def check_optimize_loop(self, opt, loop):
- expected = """
- [sum, n1]
- escape(n1)
- v = getfield_gc(n1, descr=valuedescr)
- v2 = int_sub(v, 1)
- sum2 = int_add(sum, v)
- escape(n1)
- n2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
- setfield_gc(n2, v2, descr=valuedescr)
- jump(sum2, n2)
- """
- 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)
- 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)
-
-
-
+ sum2 = int_add(sum, i1)
+ p2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ setfield_gc(p2, i2, descr=valuedescr)
+ setfield_gc(p2, p2, descr=nextdescr)
+ jump(sum2, p2)
+ """
+ boxes, getnode = self.find_nodes(ops, boxkinds={'sum': BoxInt,
+ 'sum2': BoxInt})
+ assert getnode(boxes.sum) is not getnode(boxes.sum2)
+ assert getnode(boxes.p1) is not getnode(boxes.p2)
+
+ boxp1 = getnode(boxes.p1)
+ boxp2 = getnode(boxes.p2)
+ assert not boxp1.escaped
+ assert not boxp2.escaped
+
+ assert not boxp1.curfields
+ assert boxp1.origfields[self.valuedescr] is getnode(boxes.i1)
+ assert not boxp2.origfields
+ assert boxp2.curfields[self.nextdescr] is boxp2
-def create_tests(ns):
- for name, value in ns.items():
- if (isinstance(value, type) and
- issubclass(value, BaseTestOptimize3) and
- not name.startswith('Base')):
-
- src = py.code.Source("""
- class Test%(name)sLLtype(%(name)s, LLtypeMixin, BaseTestOptimize3):
- pass
- class Test%(name)sOOtype(%(name)s, OOtypeMixin, BaseTestOptimize3):
- pass
- """ % {'name': name})
- exec src.compile() in ns
-
+class TestLLtype(BaseTestOptimize, LLtypeMixin):
+ pass
-create_tests(globals())
+class TestOOtype(BaseTestOptimize, OOtypeMixin):
+ pass
More information about the Pypy-commit
mailing list