Author: Tim Felgentreff <[email protected]>
Branch: 
Changeset: r539:a37f452bc27c
Date: 2013-12-18 15:18 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/a37f452bc27c/

Log:    add jittests like topaz does them

diff --git a/spyvm/test/jittest/__init__.py b/spyvm/test/jittest/__init__.py
new file mode 100644
diff --git a/spyvm/test/jittest/base.py b/spyvm/test/jittest/base.py
new file mode 100644
--- /dev/null
+++ b/spyvm/test/jittest/base.py
@@ -0,0 +1,121 @@
+import subprocess
+import os
+
+# TODO:
+from pypy.tool.jitlogparser.parser import SimpleParser, Op
+from pypy.tool.jitlogparser.storage import LoopStorage
+
+from rpython.jit.metainterp.resoperation import opname
+from rpython.jit.tool import oparser
+from rpython.tool import logparser
+
+
+BasePath = os.path.abspath(
+    os.path.join(
+        os.path.join(os.path.dirname(__file__), os.path.pardir),
+        os.path.pardir,
+        os.path.pardir
+    )
+)
+BenchmarkImage = os.path.join(os.path.dirname(__file__), "benchmark.image")
+
+class BaseJITTest(object):
+    def run(self, spy, tmpdir, code):
+        proc = subprocess.Popen(
+            [str(spy), "-r", code.replace("\n", "\r\n"), BenchmarkImage],
+            cwd=str(tmpdir),
+            env={"PYPYLOG": "jit-log-opt:%s" % tmpdir.join("x.pypylog")}
+        )
+        proc.wait()
+        data = logparser.parse_log_file(str(tmpdir.join("x.pypylog")), 
verbose=False)
+        data = logparser.extract_category(data, "jit-log-opt-")
+
+        storage = LoopStorage()
+        traces = [SimpleParser.parse_from_input(t) for t in data]
+        main_loops = storage.reconnect_loops(traces)
+        traces_w = []
+        for trace in traces:
+            if trace in main_loops:
+                traces_w.append(Trace(trace))
+            else:
+                traces_w[len(traces_w) - 1].addbridge(trace)
+        return traces_w
+
+    def assert_matches(self, trace, expected):
+        expected_lines = [
+            line.strip()
+            for line in expected.splitlines()
+            if line and not line.isspace()
+        ]
+        parser = Parser(None, None, {}, "lltype", None, 
invent_fail_descr=None, nonstrict=True)
+        expected_ops = [parser.parse_next_op(l) for l in expected_lines]
+        aliases = {}
+        assert len(trace) == len(expected_ops)
+        for op, expected in zip(trace, expected_ops):
+            self._assert_ops_equal(aliases, op, expected)
+
+    def _assert_ops_equal(self, aliases, op, expected):
+        assert op.name == expected.name
+        assert len(op.args) == len(expected.args)
+        for arg, expected_arg in zip(op.args, expected.args):
+            if arg in aliases:
+                arg = aliases[arg]
+            elif arg != expected_arg and expected_arg not in 
aliases.viewvalues():
+                aliases[arg] = arg = expected_arg
+            assert arg == expected_arg
+
+
+class Parser(oparser.OpParser):
+    def get_descr(self, poss_descr, allow_invent):
+        if poss_descr.startswith(("TargetToken", "<Guard")):
+            return poss_descr
+        return super(Parser, self).get_descr(poss_descr, allow_invent)
+
+    def getvar(self, arg):
+        return arg
+
+    def create_op(self, opnum, args, res, descr):
+        return Op(opname[opnum].lower(), args, res, descr)
+
+
+class Trace(object):
+    def __init__(self, trace):
+        self._trace = trace
+        self._bridges = []
+        self._bridgeops = None
+        self._loop = None
+
+    def addbridge(self, trace):
+        self._bridges.append(trace)
+
+    @property
+    def bridges(self):
+        if self._bridgeops:
+            return self._bridgeops
+        else:
+            self._bridgeops = []
+            for bridge in self._bridges:
+                self._bridgeops.append([op for op in bridge.operations if not 
op.name.startswith("debug_")])
+            return self._bridgeops
+
+    @property
+    def loop(self):
+        if self._loop:
+            return self._loop
+        else:
+            self._loop = self._parse_loop_from(self._trace)
+            return self._loop
+
+    def _parse_loop_from(self, trace, label_seen=None):
+        _loop = []
+        for idx, op in enumerate(self._trace.operations):
+            if label_seen and not op.name.startswith("debug_"):
+                _loop.append(op)
+            if op.name == "label":
+                if label_seen is None: # first label
+                    label_seen = False
+                else:
+                    label_seen = True # second label
+        if len(_loop) == 0:
+            raise ValueError("Loop body couldn't be found")
+        return _loop
diff --git a/spyvm/test/jittest/benchmark.image 
b/spyvm/test/jittest/benchmark.image
new file mode 100644
index 
0000000000000000000000000000000000000000..848cffbe175dbf07a5d4bdc4f958ce92779dd171
GIT binary patch

[cut]

diff --git a/spyvm/test/jittest/conftest.py b/spyvm/test/jittest/conftest.py
new file mode 100644
--- /dev/null
+++ b/spyvm/test/jittest/conftest.py
@@ -0,0 +1,15 @@
+import py
+
+
+def pytest_addoption(parser):
+    group = parser.getgroup("SPy JIT tests")
+    group.addoption(
+        "--spy",
+        dest="spy",
+        default=None,
+        help="Path to a compiled SPy binary"
+    )
+
+
+def pytest_funcarg__spy(request):
+    return str(py.path.local(request.config.getvalueorskip("spy")))
diff --git a/spyvm/test/jittest/test_basic.py b/spyvm/test/jittest/test_basic.py
new file mode 100644
--- /dev/null
+++ b/spyvm/test/jittest/test_basic.py
@@ -0,0 +1,93 @@
+import py
+
+from .base import BaseJITTest
+
+
+class TestBasic(BaseJITTest):
+    def test_while_loop(self, spy, tmpdir):
+        traces = self.run(spy, tmpdir, """
+        0 to: 1000000000 do: [:t|nil].
+        """)
+        self.assert_matches(traces[0].loop, """
+        guard_not_invalidated(descr=<Guard0xa15ec7c>)
+        i60 = int_le(i49, 10000)
+        guard_true(i60, descr=<Guard0xa15ec40>)
+        i61 = int_add(i49, 1)
+        i62 = int_sub(i61, -1073741824)
+        i63 = uint_lt(i62, -2147483648)
+        guard_true(i63, descr=<Guard0xa15ec04>)
+        i64 = int_sub(i57, 1)
+        setfield_gc(ConstPtr(ptr54), i64, descr=<FieldS 
spyvm.interpreter.Interpreter.inst_interrupt_check_counter 16>)
+        i65 = int_le(i64, 0)
+        guard_false(i65, descr=<Guard0xa15ebc8>)
+        jump(p0, p3, i61, p12, p14, p16, p18, p20, p22, p24, p26, p28, p30, 
p32, p34, p36, p38, i64, descr=TargetToken(169145008))
+        """)
+        self.assert_matches(traces[0].bridges[0], """
+        i18 = getfield_gc(ConstPtr(ptr17), descr=<FieldS 
spyvm.interpreter.Interpreter.inst_interrupt_counter_size 20>),
+        f20 = call(ConstClass(ll_time.ll_time_time), descr=<Callf 8 EF=4>),
+        setfield_gc(ConstPtr(ptr17), i18, descr=<FieldS 
spyvm.interpreter.Interpreter.inst_interrupt_check_counter 16>),
+        guard_no_exception(descr=<Guard0x9d3ee5c>),
+        f22 = float_mul(f20, 1000.000000),
+        call(ConstClass(set_errno), 0, descr=<Callv 0 i EF=2>),
+        f27 = call(ConstClass(fmod), f22, 536870911.000000, descr=<Callf 8 ff 
EF=2>),
+        i29 = call(ConstClass(get_errno), descr=<Calli 4 EF=2>),
+        i30 = float_ne(f27, f27),
+        guard_false(i30, descr=<Guard0x9d6ce20>),
+        i31 = int_is_true(i29),
+        guard_false(i31, descr=<Guard0x9d6cde4>),
+        i32 = cast_float_to_int(f27),
+        i33 = getfield_gc(ConstPtr(ptr17), descr=<FieldS 
spyvm.interpreter.Interpreter.inst_next_wakeup_tick 28>),
+        i34 = int_is_zero(i33),
+        guard_true(i34, descr=<Guard0x9d6cda8>),
+        i35 = same_as(i18),
+        label(p0, p1, i16, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
p14, p15, i35, descr=TargetToken(164815776)),
+        guard_class(p0, ConstClass(MethodContextShadow), 
descr=<Guard0x9d6cd6c>),
+        p37 = getfield_gc(p0, descr=<FieldP 
spyvm.shadow.MethodContextShadow.inst__w_method 44>),
+        guard_value(p37, ConstPtr(ptr38), descr=<Guard0x9d6cd30>),
+        guard_not_invalidated(descr=<Guard0x9d6ccf4>),
+        i40 = int_le(i16, 1000000000),
+        guard_true(i40, descr=<Guard0x9d6ccb8>),
+        i42 = int_add(i16, 1),
+        i44 = int_sub(i42, -1073741824),
+        i46 = uint_lt(i44, -2147483648),
+        guard_true(i46, descr=<Guard0x9d6cc7c>),
+        i48 = int_sub(i35, 1),
+        setfield_gc(ConstPtr(ptr17), i48, descr=<FieldS 
spyvm.interpreter.Interpreter.inst_interrupt_check_counter 16>),
+        i50 = int_le(i48, 0),
+        guard_false(i50, descr=<Guard0x9d6cc40>),
+        jump(p0, p1, i42, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
p14, p15, i48, descr=TargetToken(164815536))
+        """)
+
+    def test_constant_string(self, spy, tmpdir):
+        traces = self.run(spy, tmpdir, """
+        | i |
+        i := 0.
+        [i <= 10000] whileTrue: [ i := i + 'a' size].
+        ^ i
+        """)
+        self.assert_matches(traces[0].loop, """
+        label(p0, p3, i58, p12, p14, p16, p18, p20, p22, p24, p26, p28, p30, 
p32, p34, p36, p38, i65, descr=TargetToken(153187472))
+        debug_merge_point(0, 0, '2: [0x10]pushTemporaryVariableBytecode 
(codeTest1387373494)')
+        guard_not_invalidated(descr=<Guard0x92520c4>)
+        debug_merge_point(0, 0, '3: [0x21]pushLiteralConstantBytecode 
(codeTest1387373494)')
+        debug_merge_point(0, 0, '4: [0xb4]bytecodePrimLessOrEqual 
(codeTest1387373494)')
+        i68 = int_le(i58, 10000)
+        guard_true(i68, descr=<Guard0x9252088>)
+        debug_merge_point(0, 0, '5: [0x9e]shortConditionalJump 
(codeTest1387373494)')
+        debug_merge_point(0, 0, '6: [0x10]pushTemporaryVariableBytecode 
(codeTest1387373494)')
+        debug_merge_point(0, 0, '7: [0x20]pushLiteralConstantBytecode 
(codeTest1387373494)')
+        debug_merge_point(0, 0, '8: [0xc2]bytecodePrimSize 
(codeTest1387373494)')
+        debug_merge_point(0, 0, '9: [0xb0]bytecodePrimAdd 
(codeTest1387373494)')
+        i69 = int_add(i58, 1)
+        i70 = int_sub(i69, -1073741824)
+        i71 = uint_lt(i70, -2147483648)
+        guard_true(i71, descr=<Guard0x925204c>)
+        debug_merge_point(0, 0, '10: 
[0x68]storeAndPopTemporaryVariableBytecode (codeTest1387373494)')
+        debug_merge_point(0, 0, '11: [0xa3]longUnconditionalJump 
(codeTest1387373494)')
+        i72 = int_sub(i65, 1)
+        setfield_gc(ConstPtr(ptr55), i72, descr=<FieldS 
spyvm.interpreter.Interpreter.inst_interrupt_check_counter 16>)
+        i73 = int_le(i72, 0)
+        guard_false(i73, descr=<Guard0x9252010>)
+        debug_merge_point(0, 0, '2: [0x10]pushTemporaryVariableBytecode 
(codeTest1387373494)')
+        jump(p0, p3, i69, p12, p14, p16, p18, p20, p22, p24, p26, p28, p30, 
p32, p34, p36, p38, i72, descr=TargetToken(153187472))
+        """)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to