[pypy-svn] r73975 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Thu Apr 22 15:19:15 CEST 2010


Author: arigo
Date: Thu Apr 22 15:19:13 2010
New Revision: 73975

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
Log:
Proper support for lists of registers.
They are actually ListOfKinds, not just lists.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py	Thu Apr 22 15:19:13 2010
@@ -1,5 +1,6 @@
 from pypy.jit.metainterp.history import AbstractValue, getkind
 from pypy.jit.codewriter.flatten import Register, Label, TLabel, KINDS
+from pypy.jit.codewriter.flatten import ListOfKind
 from pypy.objspace.flow.model import Constant
 
 
@@ -30,72 +31,109 @@
         self.insns = {}
 
     def assemble(self, ssarepr):
-        code = []
-        constants_dict = {}
-        constants_i = []
-        constants_r = []
-        constants_f = []
-        label_positions = {}
-        tlabel_positions = []
-        highest_regs = dict.fromkeys(KINDS, 0)
+        self.setup()
         for insn in ssarepr.insns:
-            if isinstance(insn[0], Label):
-                label_positions[insn[0].name] = len(code)
-                continue
-            startposition = len(code)
-            code.append("temporary placeholder")
-            #
-            argcodes = []
-            for x in insn[1:]:
-                if isinstance(x, Register):
-                    if x.index > highest_regs[x.kind]:
-                        highest_regs[x.kind] = x.index
-                    code.append(chr(x.index))
-                    argcodes.append(x.kind[0])
-                elif isinstance(x, Constant):
-                    kind = getkind(x.concretetype)
-                    if kind == 'int' and -128 <= x.value <= 127:
-                        code.append(chr(x.value & 0xFF))
-                        argcodes.append('c')
-                    else:
-                        if x not in constants_dict:
-                            if kind == 'int':
-                                constants = constants_i
-                            elif kind == 'ref':
-                                constants = constants_r
-                            elif kind == 'float':
-                                constants = constants_f
-                            else:
-                                raise NotImplementedError(x)
-                            constants.append(x.value)
-                            constants_dict[x] = 256 - len(constants)
-                        code.append(chr(constants_dict[x]))
-                        argcodes.append(kind[0])
-                elif isinstance(x, TLabel):
-                    tlabel_positions.append((x.name, len(code)))
-                    code.append("temp 1")
-                    code.append("temp 2")
-                    argcodes.append('L')
+            self.write_insn(insn)
+        self.fix_labels()
+        self.check_result()
+        return self.make_jitcode(ssarepr.name)
+
+    def setup(self):
+        self.code = []
+        self.constants_dict = {}
+        self.constants_i = []
+        self.constants_r = []
+        self.constants_f = []
+        self.label_positions = {}
+        self.tlabel_positions = []
+        self.highest_regs = dict.fromkeys(KINDS, 0)
+
+    def emit_reg(self, reg):
+        if reg.index > self.highest_regs[reg.kind]:
+            self.highest_regs[reg.kind] = reg.index
+        self.code.append(chr(reg.index))
+
+    def emit_const(self, const, kind):
+        if const not in self.constants_dict:
+            if kind == 'int':
+                constants = self.constants_i
+            elif kind == 'ref':
+                constants = self.constants_r
+            elif kind == 'float':
+                constants = self.constants_f
+            else:
+                raise NotImplementedError(const)
+            constants.append(const.value)
+            self.constants_dict[const] = 256 - len(constants)
+        self.code.append(chr(self.constants_dict[const]))
+
+    def write_insn(self, insn):
+        if isinstance(insn[0], Label):
+            self.label_positions[insn[0].name] = len(self.code)
+            return
+        startposition = len(self.code)
+        self.code.append("temporary placeholder")
+        #
+        argcodes = []
+        for x in insn[1:]:
+            if isinstance(x, Register):
+                self.emit_reg(x)
+                argcodes.append(x.kind[0])
+            elif isinstance(x, Constant):
+                kind = getkind(x.concretetype)
+                if kind == 'int' and -128 <= x.value <= 127:
+                    self.code.append(chr(x.value & 0xFF))
+                    argcodes.append('c')
                 else:
-                    raise NotImplementedError(x)
-            #
-            key = insn[0] + '/' + ''.join(argcodes)
-            num = self.insns.setdefault(key, len(self.insns))
-            code[startposition] = chr(num)
+                    self.emit_const(x, kind)
+                    argcodes.append(kind[0])
+            elif isinstance(x, TLabel):
+                self.tlabel_positions.append((x.name, len(self.code)))
+                self.code.append("temp 1")
+                self.code.append("temp 2")
+                argcodes.append('L')
+            elif isinstance(x, ListOfKind):
+                itemkind = x.kind
+                lst = list(x)
+                assert len(lst) <= 255, "list too long!"
+                self.code.append(chr(len(lst)))
+                for item in lst:
+                    if isinstance(item, Register):
+                        assert itemkind == item.kind
+                        self.emit_reg(item)
+                    elif isinstance(item, Constant):
+                        assert itemkind == getkind(item.concretetype)
+                        self.emit_const(item, itemkind)
+                    else:
+                        raise NotImplementedError("found in ListOfKind(): %r"
+                                                  % (item,))
+                argcodes.append(itemkind[0].upper())
+            else:
+                raise NotImplementedError(x)
         #
-        for name, pos in tlabel_positions:
-            assert code[pos  ] == "temp 1"
-            assert code[pos+1] == "temp 2"
-            target = label_positions[name]
+        key = insn[0] + '/' + ''.join(argcodes)
+        num = self.insns.setdefault(key, len(self.insns))
+        self.code[startposition] = chr(num)
+
+    def fix_labels(self):
+        for name, pos in self.tlabel_positions:
+            assert self.code[pos  ] == "temp 1"
+            assert self.code[pos+1] == "temp 2"
+            target = self.label_positions[name]
             assert 0 <= target <= 0xFFFF
-            code[pos  ] = chr(target & 0xFF)
-            code[pos+1] = chr(target >> 8)
-        #
+            self.code[pos  ] = chr(target & 0xFF)
+            self.code[pos+1] = chr(target >> 8)
+
+    def check_result(self):
         # Limitation of the number of registers, from the single-byte encoding
-        assert highest_regs['int'] + len(constants_i) <= 256
-        assert highest_regs['ref'] + len(constants_r) <= 256
-        assert highest_regs['float'] + len(constants_f) <= 256
-        #
-        jitcode = JitCode(ssarepr.name)
-        jitcode.setup(''.join(code), constants_i, constants_r, constants_f)
+        assert self.highest_regs['int'] + len(self.constants_i) <= 256
+        assert self.highest_regs['ref'] + len(self.constants_r) <= 256
+        assert self.highest_regs['float'] + len(self.constants_f) <= 256
+
+    def make_jitcode(self, name):
+        jitcode = JitCode(name)
+        jitcode.setup(''.join(self.code),
+                      self.constants_i,
+                      self.constants_r,
+                      self.constants_f)
         return jitcode

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	Thu Apr 22 15:19:13 2010
@@ -1,4 +1,4 @@
-from pypy.objspace.flow.model import Variable
+from pypy.objspace.flow.model import Variable, Constant
 from pypy.jit.metainterp.history import getkind
 from pypy.rpython.lltypesystem import lltype
 
@@ -26,9 +26,22 @@
 
 class Register(object):
     def __init__(self, kind, index):
-        self.kind = kind
+        self.kind = kind          # 'int', 'ref' or 'float'
         self.index = index
 
+class ListOfKind(object):
+    # a list of Regs/Consts, all of the same 'kind'.
+    # We cannot use a plain list, because we wouldn't know what 'kind' of
+    # Regs/Consts would be expected in case the list is empty.
+    def __init__(self, kind, content):
+        assert kind in KINDS
+        self.kind = kind
+        self.content = tuple(content)
+    def __repr__(self):
+        return '%s%s' % (self.kind[0], self.content)
+    def __iter__(self):
+        return iter(self.content)
+
 KINDS = ['int', 'ref', 'float']
 
 # ____________________________________________________________
@@ -161,6 +174,8 @@
                     for v, w in result:
                         self.emitline('%s_copy' % kind, v, w)
                 else:
+                    frm = ListOfKind(kind, frm)
+                    to  = ListOfKind(kind, to)
                     self.emitline('%s_rename' % kind, frm, to)
 
     def emitline(self, *line):
@@ -171,13 +186,17 @@
         for v in arglist:
             if isinstance(v, Variable):
                 v = self.getcolor(v)
-            elif isinstance(v, list):
-                lst = v
-                v = []
-                for x in lst:
+            elif isinstance(v, Constant):
+                pass
+            elif isinstance(v, ListOfKind):
+                lst = []
+                for x in v:
                     if isinstance(x, Variable):
                         x = self.getcolor(x)
-                    v.append(x)
+                    lst.append(x)
+                v = ListOfKind(v.kind, lst)
+            else:
+                raise NotImplementedError(type(v))
             args.append(v)
         return args
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py	Thu Apr 22 15:19:13 2010
@@ -1,9 +1,10 @@
 import py
 from pypy.objspace.flow.model import Constant
 from pypy.jit.codewriter.flatten import SSARepr, Label, TLabel, Register
+from pypy.jit.codewriter.flatten import ListOfKind
 
 
-def format_assembler(ssarepr):
+def format_assembler(ssarepr, dump=True):
     """For testing: format a SSARepr as a multiline string."""
     from cStringIO import StringIO
     seen = {}
@@ -15,8 +16,8 @@
             return '$' + str(x.value)
         elif isinstance(x, TLabel):
             return getlabelname(x)
-        elif isinstance(x, list):
-            return '[%s]' % ', '.join(map(repr, x))
+        elif isinstance(x, ListOfKind):
+            return '%s[%s]' % (x.kind[0], ', '.join(map(repr, x)))
         else:
             return '<unknown object: %r>' % (x,)
     #
@@ -43,4 +44,8 @@
                 print >> output, ', '.join(map(repr, asm[1:]))
             else:
                 print >> output
-    return output.getvalue()
+    res = output.getvalue()
+    if dump:
+        print res
+    return res
+

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	Thu Apr 22 15:19:13 2010
@@ -1,6 +1,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.metainterp.history import getkind
 from pypy.objspace.flow.model import SpaceOperation
+from pypy.jit.codewriter.flatten import ListOfKind
 
 
 def transform_graph(graph):
@@ -58,9 +59,9 @@
     elif args_i: kinds = 'ir'
     else:        kinds = 'r'
     sublists = []
-    if 'i' in kinds: sublists.append(args_i)
-    if 'r' in kinds: sublists.append(args_r)
-    if 'f' in kinds: sublists.append(args_f)
+    if 'i' in kinds: sublists.append(ListOfKind('int', args_i))
+    if 'r' in kinds: sublists.append(ListOfKind('ref', args_r))
+    if 'f' in kinds: sublists.append(ListOfKind('float', args_f))
     reskind = getkind(op.result.concretetype)[0]
     return SpaceOperation('residual_call_%s_%s' % (kinds, reskind),
                           [op.args[0]] + sublists,

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py	Thu Apr 22 15:19:13 2010
@@ -1,5 +1,6 @@
 from pypy.jit.codewriter.assembler import Assembler
 from pypy.jit.codewriter.flatten import SSARepr, Label, TLabel, Register
+from pypy.jit.codewriter.flatten import ListOfKind
 from pypy.objspace.flow.model import Constant
 from pypy.rpython.lltypesystem import lltype
 
@@ -79,3 +80,16 @@
                                'int_sub/ici': 2,
                                'goto/L': 3,
                                'int_return/i': 4}
+
+def test_assemble_list():
+    ssarepr = SSARepr("test")
+    i0, i1 = Register('int', 0x16), Register('int', 0x17)
+    ssarepr.insns = [
+        ('foobar', ListOfKind('int', [i0, i1, Constant(42, lltype.Signed)]),
+                   ListOfKind('ref', [])),
+        ]
+    assembler = Assembler()
+    jitcode = assembler.assemble(ssarepr)
+    assert jitcode.code == "\x00\x03\x16\x17\xFF\x00"
+    assert assembler.insns == {'foobar/IR': 0}
+    assert jitcode.constants_i == [42]

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	Thu Apr 22 15:19:13 2010
@@ -1,7 +1,7 @@
 import py
 from pypy.jit.codewriter import support
 from pypy.jit.codewriter.flatten import flatten_graph, reorder_renaming_list
-from pypy.jit.codewriter.flatten import GraphFlattener
+from pypy.jit.codewriter.flatten import GraphFlattener, ListOfKind
 from pypy.jit.codewriter.format import format_assembler
 from pypy.jit.codewriter.jitter import transform_graph
 from pypy.rpython.lltypesystem import lltype, rclass, rstr
@@ -128,11 +128,11 @@
         v5 = varoftype(lltype.Float)
         op = SpaceOperation('residual_call_ir_f',
                             [Constant(12345, lltype.Signed),  # function ptr
-                             [v1, v2],              # int args
-                             [v3, v4]],             # ref args
+                             ListOfKind('int', [v1, v2]),     # int args
+                             ListOfKind('ref', [v3, v4])],    # ref args
                             v5)                    # result
         flattener = GraphFlattener(None, fake_regallocs())
         flattener.serialize_op(op)
         self.assert_format(flattener.ssarepr, """
-            residual_call_ir_f $12345, [%i0, %i1], [%r0, %r1], %f0
+            residual_call_ir_f $12345, i[%i0, %i1], r[%r0, %r1], %f0
         """)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py	Thu Apr 22 15:19:13 2010
@@ -2,19 +2,19 @@
 from pypy.objspace.flow.model import Constant
 from pypy.jit.codewriter.format import format_assembler
 from pypy.jit.codewriter.flatten import Label, TLabel, SSARepr, Register
+from pypy.jit.codewriter.flatten import ListOfKind
+from pypy.rpython.lltypesystem import lltype
 
 
 def test_format_assembler_simple():
     ssarepr = SSARepr("test")
     i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2)
     ssarepr.insns = [
-        ('foobar', [i0, i1]),
         ('int_add', i0, i1, i2),
         ('int_return', i2),
         ]
     asm = format_assembler(ssarepr)
     expected = """
-        foobar [%i0, %i1]
         int_add %i0, %i1, %i2
         int_return %i2
     """
@@ -36,7 +36,6 @@
     ssarepr = SSARepr("test")
     i0, i1 = Register('int', 0), Register('int', 1)
     ssarepr.insns = [
-        ('foobar', [i0, i1]),
         (Label('L1'),),
         ('goto_if_not_int_gt', TLabel('L2'), i0, Constant(0)),
         ('int_add', i1, i0, i1),
@@ -47,7 +46,6 @@
         ]
     asm = format_assembler(ssarepr)
     expected = """
-        foobar [%i0, %i1]
         L1:
         goto_if_not_int_gt L2, %i0, $0
         int_add %i1, %i0, %i1
@@ -57,3 +55,15 @@
         int_return %i1
     """
     assert asm == str(py.code.Source(expected)).strip() + '\n'
+
+def test_format_assembler_list():
+    ssarepr = SSARepr("test")
+    i0, i1 = Register('int', 0), Register('int', 1)
+    ssarepr.insns = [
+        ('foobar', ListOfKind('int', [i0, Constant(123, lltype.Signed), i1])),
+        ]
+    asm = format_assembler(ssarepr)
+    expected = """
+        foobar i[%i0, $123, %i1]
+    """
+    assert asm == str(py.code.Source(expected)).strip() + '\n'

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	Thu Apr 22 15:19:13 2010
@@ -84,6 +84,7 @@
     assert op1.result == op.result
     assert op1.args[0] == op.args[0]
     assert len(op1.args) == 1 + len(expectedkind)
-    for sublist, kind in zip(op1.args[1:], expectedkind):
-        assert sublist == [v for v in op.args[1:]
-                             if getkind(v.concretetype).startswith(kind)]
+    for sublist, kind1 in zip(op1.args[1:], expectedkind):
+        assert sublist.kind.startswith(kind1)
+        assert list(sublist) == [v for v in op.args[1:]
+                                 if getkind(v.concretetype) == sublist.kind]

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	Thu Apr 22 15:19:13 2010
@@ -69,7 +69,7 @@
             L1:
             int_gt %i0, $0, %i2
             goto_if_not L2, %i2
-            int_rename [%i1, %i0], [%i0, %i1]
+            int_rename i[%i1, %i0], i[%i0, %i1]
             goto L1
             L2:
             int_return %i1
@@ -102,7 +102,7 @@
             L1:
             int_gt %i0, $0, %i3
             goto_if_not L2, %i3
-            int_rename [%i1, %i2, %i0], [%i0, %i1, %i2]
+            int_rename i[%i1, %i2, %i0], i[%i0, %i1, %i2]
             goto L1
             L2:
             int_return %i1



More information about the Pypy-commit mailing list