[pypy-commit] pypy default: start implementing slicing assembler into ops

fijal noreply at buildbot.pypy.org
Wed Jul 6 18:29:00 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r45364:6e65afd1e3a4
Date: 2011-07-06 18:37 +0200
http://bitbucket.org/pypy/pypy/changeset/6e65afd1e3a4/

Log:	start implementing slicing assembler into ops

diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py
--- a/pypy/jit/tool/oparser.py
+++ b/pypy/jit/tool/oparser.py
@@ -337,6 +337,11 @@
                 num += 1
         return num, ops, last_offset
 
+    def postprocess(self, loop):
+        """ A hook that can be overloaded to do some postprocessing
+        """
+        return loop
+
     def parse_offset(self, line):
         if line.startswith('+'):
             # it begins with an offset, like: "+10: i1 = int_add(...)"
diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -5,6 +5,8 @@
 
 class Op(object):
     bridge = None
+    offset = None
+    asm = None
 
     def __init__(self, name, args, res, descr):
         self.name = name
@@ -54,10 +56,53 @@
     Op = Op
     use_mock_model = True
 
+    def postprocess(self, loop, backend_dump=None, backend_tp=None,
+                    loop_start=0, dump_start=0):
+        if backend_dump is not None:
+            raw_asm = self._asm_disassemble(backend_dump.decode('hex'),
+                                            backend_tp, dump_start)
+            asm = []
+            start = 0
+            for elem in raw_asm:
+                if len(elem.split("\t")) != 3:
+                    continue
+                adr, _, v = elem.split("\t")
+                if not start:
+                    start = int(adr.strip(":"), 16)
+                ofs = int(adr.strip(":"), 16) - start
+                if ofs >= 0:
+                    asm.append((ofs, v.strip("\n")))
+            asm_index = 0
+            for i, op in enumerate(loop.operations):
+                end = 0
+                j = i + 1
+                while end == 0:
+                    if j == len(loop.operations):
+                        end = loop.last_offset
+                        break
+                    if loop.operations[j].offset is None:
+                        j += 1
+                    else:
+                        end = loop.operations[j].offset
+                if op.offset is not None:
+                    while asm[asm_index][0] < op.offset:
+                        asm_index += 1
+                    end_index = asm_index
+                    while asm[end_index][0] < end:
+                        end_index += 1
+                    op.asm = '\n'.join([asm[i][1] for i in range(asm_index, end_index)])
+        return loop
+                    
+    def _asm_disassemble(self, d, origin_addr, tp):
+        from pypy.jit.backend.x86.tool.viewcode import machine_code_dump
+        return list(machine_code_dump(d, tp, origin_addr))
+
     @classmethod
-    def parse_from_input(cls, input):
-        return cls(input, None, {}, 'lltype', None,
-                   nonstrict=True).parse()
+    def parse_from_input(cls, input, **kwds):
+        parser = cls(input, None, {}, 'lltype', None,
+                     nonstrict=True)
+        loop = parser.parse()
+        return parser.postprocess(loop, **kwds)
 
     def parse_args(self, opname, argspec):
         if not argspec.strip():
diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py
--- a/pypy/tool/jitlogparser/test/test_parser.py
+++ b/pypy/tool/jitlogparser/test/test_parser.py
@@ -5,8 +5,8 @@
 from pypy.tool.jitlogparser.storage import LoopStorage
 import py
 
-def parse(input):
-    return SimpleParser.parse_from_input(input)
+def parse(input, **kwds):
+    return SimpleParser.parse_from_input(input, **kwds)
 
 
 def test_parse():
@@ -179,3 +179,31 @@
     ops = Function.from_operations(loop.operations, LoopStorage())
     chunk = ops.chunks[0]
     assert chunk.bytecode_name == 'StrLiteralSearch'
+
+def test_parsing_assembler():
+    backend_dump = "554889E5534154415541564157488DA500000000488B042590C5540148C7042590C554010000000048898570FFFFFF488B042598C5540148C7042598C554010000000048898568FFFFFF488B0425A0C5540148C70425A0C554010000000048898560FFFFFF488B0425A8C5540148C70425A8C554010000000048898558FFFFFF4C8B3C2550525B0149BB30E06C96FC7F00004D8B334983C60149BB30E06C96FC7F00004D89334981FF102700000F8D000000004983C7014C8B342580F76A024983EE014C89342580F76A024983FE000F8C00000000E9AEFFFFFF488B042588F76A024829E0483B042580EC3C01760D49BB05F30894FC7F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E954FFFFFF49BB00F00894FC7F000041FFD34440484C3D030300000049BB00F00894FC7F000041FFD34440484C3D070304000000"
+    dump_start = 0x7f3b0b2e63d5
+    loop = parse("""
+    # Loop 0 : loop with 19 ops
+    [p0, p1, p2, p3, i4]
+    debug_merge_point(0, '<code object f. file 'x.py'. line 2> #15 COMPARE_OP')
+    +166: i6 = int_lt(i4, 10000)
+    guard_true(i6, descr=<Guard3>) [p1, p0, p2, p3, i4]
+    debug_merge_point(0, '<code object f. file 'x.py'. line 2> #27 INPLACE_ADD')
+    +179: i8 = int_add(i4, 1)
+    debug_merge_point(0, '<code object f. file 'x.py'. line 2> #31 JUMP_ABSOLUTE')
+    +183: i10 = getfield_raw(40564608, descr=<SignedFieldDescr pypysig_long_struct.c_value 0>)
+    +191: i12 = int_sub(i10, 1)
+    +195: setfield_raw(40564608, i12, descr=<SignedFieldDescr pypysig_long_struct.c_value 0>)
+    +203: i14 = int_lt(i12, 0)
+    guard_false(i14, descr=<Guard4>) [p1, p0, p2, p3, i8, None]
+    debug_merge_point(0, '<code object f. file 'x.py'. line 2> #9 LOAD_FAST')
+    +213: jump(p0, p1, p2, p3, i8, descr=<Loop0>)
+    +218: --end of the loop--""", backend_dump=backend_dump,
+                 dump_start=dump_start,
+                 backend_tp='x86_64',
+                 loop_start=0x7f3b0b2e645d)
+    cmp = loop.operations[1]
+    assert 'jge' in cmp.asm
+    assert '0x2710' in cmp.asm
+    assert 'jmp' in loop.operations[-1].asm


More information about the pypy-commit mailing list