[pypy-svn] r74629 - in pypy/branch/blackhole-improvement/pypy/jit: codewriter codewriter/test metainterp

arigo at codespeak.net arigo at codespeak.net
Fri May 21 15:46:59 CEST 2010


Author: arigo
Date: Fri May 21 15:46:57 2010
New Revision: 74629

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.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/jtransform.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py
Log:
Finish the refactoring of codewriter to the new format of -live- operations.
Now starting to work on pyjitpl...


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	Fri May 21 15:46:57 2010
@@ -45,7 +45,6 @@
         self.switchdictdescrs = []
         self.count_regs = dict.fromkeys(KINDS, 0)
         self.liveness = {}
-        self.nextlive = None
         self.startpoints = set()
         self.alllabels = set()
 
@@ -88,21 +87,18 @@
         return False
 
     def write_insn(self, insn):
+        if insn[0] == '---':
+            return
         if isinstance(insn[0], Label):
             self.label_positions[insn[0].name] = len(self.code)
             return
         if insn[0] == '-live-':
-            assert self.nextlive is None
-            self.nextlive = (
-                self.get_liveness_info(insn, 'int'),
-                self.get_liveness_info(insn, 'ref'),
-                self.get_liveness_info(insn, 'float'))
-            return
-        if insn[0] == 'keepalive':
-            # The 'keepalive' instruction is useful when doing register
-            # allocation, to ensure that the register holding the value is
-            # not overwritten too early.  But it does not need to be
-            # present at all in the final code.
+            key = len(self.code)
+            live_i, live_r, live_f = self.liveness.get(key, ("", "", ""))
+            live_i = self.get_liveness_info(live_i, insn[1:], 'int')
+            live_r = self.get_liveness_info(live_r, insn[1:], 'ref')
+            live_f = self.get_liveness_info(live_f, insn[1:], 'float')
+            self.liveness[key] = live_i, live_r, live_f
             return
         startposition = len(self.code)
         self.code.append("temporary placeholder")
@@ -154,24 +150,29 @@
                 argcodes.append('d')
             elif isinstance(x, IndirectCallTargets):
                 self.indirectcalltargets.update(x.lst)
+            elif x == '->':
+                assert '>' not in argcodes
+                argcodes.append('>')
             else:
                 raise NotImplementedError(x)
         #
         opname = insn[0]
-        if opname.startswith('G_'): opname = opname[2:]
+        assert '>' not in argcodes or argcodes.index('>') == len(argcodes) - 2
         key = opname + '/' + ''.join(argcodes)
         num = self.insns.setdefault(key, len(self.insns))
         self.code[startposition] = chr(num)
         self.startpoints.add(startposition)
-        #
-        if self.nextlive is not None:
-            self.liveness[len(self.code)] = self.nextlive
-            self.nextlive = None
-
-    def get_liveness_info(self, insn, kind):
-        lives = [chr(reg.index) for reg in insn[1:] if reg.kind == kind]
-        lives.sort()
-        return ''.join(lives)
+
+    def get_liveness_info(self, prevstring, args, kind):
+        """Return a string whose characters are register numbers.
+        We sort the numbers, too, to increase the chances of duplicate
+        strings (which are collapsed into a single string during translation).
+        """
+        lives = set(prevstring)    # set of characters
+        for reg in args:
+            if isinstance(reg, Register) and reg.kind == kind:
+                lives.add(chr(reg.index))
+        return ''.join(sorted(lives))
 
     def fix_labels(self):
         for name, pos in self.tlabel_positions:

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py	Fri May 21 15:46:57 2010
@@ -38,20 +38,20 @@
         # that we want in the JitCode, but still as a control flow graph
         transform_graph(graph, self.cpu, self.callcontrol, portal)
         #
-        # step 2a: perform register allocation on it
+        # step 2: perform register allocation on it
         regallocs = {}
         for kind in KINDS:
             regallocs[kind] = perform_register_allocation(graph, kind)
         #
-        # step 2b: compute the liveness around certain operations
-        compute_liveness(graph)
-        #
         # step 3: flatten the graph to produce human-readable "assembler",
         # which means mostly producing a linear list of operations and
         # inserting jumps or conditional jumps.  This is a list of tuples
         # of the shape ("opname", arg1, ..., argN) or (Label(...),).
         ssarepr = flatten_graph(graph, regallocs)
         #
+        # step 3b: compute the liveness around certain operations
+        compute_liveness(ssarepr)
+        #
         # print the resulting assembler
         self.print_ssa_repr(ssarepr, portal, verbose)
         #

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	Fri May 21 15:46:57 2010
@@ -168,14 +168,18 @@
         elif block.exitswitch is c_last_exception:
             # An exception block. See test_exc_exitswitch in test_flatten.py
             # for an example of what kind of code this makes.
-            lastopname = block.operations[-1].opname
-            assert lastopname != '-live-'
+            index = -1
+            while True:
+                lastopname = block.operations[index].opname
+                if lastopname != '-live-':
+                    break
+                index -= 1
             assert block.exits[0].exitcase is None # is this always True?
             #
             if not self._include_all_exc_links:
-                if (len(block.operations) == 1 or
-                    block.operations[-2].opname != '-live-'):
-                    # cannot actually raise
+                if index == -1:
+                    # cannot raise: the last instruction is not
+                    # actually a '-live-'
                     self.make_link(block.exits[0])
                     return
             # 
@@ -212,8 +216,7 @@
             opname = 'goto_if_not'
             if isinstance(block.exitswitch, tuple):
                 # special case produced by jtransform.optimize_goto_if_not()
-                if block.exitswitch[0] != 'int_is_true':
-                    opname = 'goto_if_not_' + block.exitswitch[0]
+                opname = 'goto_if_not_' + block.exitswitch[0]
                 opargs = block.exitswitch[1:]
             else:
                 assert block.exitswitch.concretetype == lltype.Bool
@@ -221,6 +224,7 @@
             #
             lst = self.flatten_list(opargs) + [TLabel(linkfalse)]
             self.emitline(opname, *lst)
+            self.emitline('-live-', TLabel(linkfalse))
             # true path:
             self.make_link(linktrue)
             # false path:
@@ -236,6 +240,7 @@
                 else:
                     self.emitline("---")
             #
+            self.emitline('-live-')
             switches = [link for link in block.exits
                         if link.exitcase != 'default']
             switches.sort(key=lambda link: link.llexitcase)

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	Fri May 21 15:46:57 2010
@@ -50,7 +50,7 @@
     #
     output = StringIO()
     insns = ssarepr.insns
-    if insns[-1] == ('---',):
+    if insns and insns[-1] == ('---',):
         insns = insns[:-1]
     for asm in insns:
         if isinstance(asm[0], Label):

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py	Fri May 21 15:46:57 2010
@@ -580,6 +580,7 @@
                        ('cast_float_to_uint', 'cast_float_to_int'),
 
                        ('int_add_nonneg_ovf', 'int_add_ovf'),
+                       ('keepalive', '-live-'),
 
                        ('char_lt', 'int_lt'),
                        ('char_le', 'int_le'),

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	Fri May 21 15:46:57 2010
@@ -12,14 +12,14 @@
     ssarepr = SSARepr("test")
     i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2)
     ssarepr.insns = [
-        ('int_add', i0, i1, i2),
+        ('int_add', i0, i1, '->', i2),
         ('int_return', i2),
         ]
     assembler = Assembler()
     jitcode = assembler.assemble(ssarepr)
     assert jitcode.code == ("\x00\x00\x01\x02"
                             "\x01\x02")
-    assert assembler.insns == {'int_add/iii': 0,
+    assert assembler.insns == {'int_add/ii>i': 0,
                                'int_return/i': 1}
     assert jitcode.num_regs_i() == 3
     assert jitcode.num_regs_r() == 0
@@ -94,8 +94,8 @@
     ssarepr.insns = [
         (Label('L1'),),
         ('goto_if_not_int_gt', i0, Constant(4, lltype.Signed), TLabel('L2')),
-        ('int_add', i1, i0, i1),
-        ('int_sub', i0, Constant(1, lltype.Signed), i0),
+        ('int_add', i1, i0, '->', i1),
+        ('int_sub', i0, Constant(1, lltype.Signed), '->', i0),
         ('goto', TLabel('L1')),
         (Label('L2'),),
         ('int_return', i1),
@@ -108,8 +108,8 @@
                             "\x03\x00\x00"
                             "\x04\x17")
     assert assembler.insns == {'goto_if_not_int_gt/icL': 0,
-                               'int_add/iii': 1,
-                               'int_sub/ici': 2,
+                               'int_add/ii>i': 1,
+                               'int_sub/ic>i': 2,
                                'goto/L': 3,
                                'int_return/i': 4}
 
@@ -149,13 +149,6 @@
     assembler.assemble(ssarepr)
     assert assembler.indirectcalltargets == set(lst1).union(lst2)
 
-def test_assemble_keepalive():
-    ssarepr = SSARepr("test")
-    ssarepr.insns = [('keepalive', Register('ref', 2))]
-    assembler = Assembler()
-    jitcode = assembler.assemble(ssarepr)
-    assert jitcode.code == ""     # the keepalive is removed
-
 def test_num_regs():
     assembler = Assembler()
     ssarepr = SSARepr("test")
@@ -176,37 +169,20 @@
 def test_liveness():
     ssarepr = SSARepr("test")
     i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2)
-    i3, i4, i5 = Register('int', 3), Register('int', 4), Register('int', 5)
     ssarepr.insns = [
-        ('-live-', i0),
-        ('G_int_add', i0, Constant(10, lltype.Signed), i1),
+        ('int_add', i0, Constant(10, lltype.Signed), '->', i1),
         ('-live-', i0, i1),
-        ('G_int_add', i0, Constant(3, lltype.Signed), i2),
-        ('-live-', i0),
-        ('G_int_mul', i1, i2, i3),
-        ('-live-', i3),
-        ('G_int_add', i0, Constant(6, lltype.Signed), i4),
-        ('-live-',),
-        ('G_int_mul', i3, i4, i5),
-        ('int_return', i5),
+        ('-live-', i1, i2),
+        ('int_add', i0, Constant(3, lltype.Signed), '->', i2),
+        ('-live-', i2),
         ]
     assembler = Assembler()
     jitcode = assembler.assemble(ssarepr)
     assert jitcode.code == ("\x00\x00\x0A\x01"   # ends at 4
-                            "\x00\x00\x03\x02"   # ends at 8
-                            "\x01\x01\x02\x03"   # ends at 12
-                            "\x00\x00\x06\x04"   # ends at 16
-                            "\x01\x03\x04\x05"   # ends at 20
-                            "\x02\x05")
-    assert assembler.insns == {'int_add/ici': 0,
-                               'int_mul/iii': 1,
-                               'int_return/i': 2}
-    py.test.raises(MissingLiveness, jitcode._live_vars, 0)
-    py.test.raises(MissingLiveness, jitcode._live_vars, 3)
-    py.test.raises(MissingLiveness, jitcode._live_vars, 5)
-    py.test.raises(MissingLiveness, jitcode._live_vars, 24)
-    assert jitcode._live_vars(4) == '%i0'
-    assert jitcode._live_vars(8) == '%i0 %i1'
-    assert jitcode._live_vars(12) == '%i0'
-    assert jitcode._live_vars(16) == '%i3'
-    assert jitcode._live_vars(20) == ''
+                            "\x00\x00\x03\x02")  # ends at 8
+    assert assembler.insns == {'int_add/ic>i': 0}
+    for i in range(8):
+        if i != 4:
+            py.test.raises(MissingLiveness, jitcode._live_vars, i)
+    assert jitcode._live_vars(4) == '%i0 %i1 %i2'
+    assert jitcode._live_vars(8) == '%i2'

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	Fri May 21 15:46:57 2010
@@ -36,8 +36,8 @@
                             "\x03\x00\x00"
                             "\x04\x01")
     assert cw.assembler.insns == {'goto_if_not_int_gt/icL': 0,
-                                  'int_add/iii': 1,
-                                  'int_sub/ici': 2,
+                                  'int_add/ii>i': 1,
+                                  'int_sub/ic>i': 2,
                                   'goto/L': 3,
                                   'int_return/i': 4}
     assert jitcode.num_regs_i() == 2

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	Fri May 21 15:46:57 2010
@@ -95,18 +95,18 @@
         if transform:
             from pypy.jit.codewriter.jtransform import transform_graph
             transform_graph(graphs[0], FakeCPU(), FakeCallControl())
-        if liveness:
-            from pypy.jit.codewriter.liveness import compute_liveness
-            compute_liveness(graphs[0])
         ssarepr = flatten_graph(graphs[0], fake_regallocs(),
                                 _include_all_exc_links=not transform)
+        if liveness:
+            from pypy.jit.codewriter.liveness import compute_liveness
+            compute_liveness(ssarepr)
         assert_format(ssarepr, expected)
 
     def test_simple(self):
         def f(n):
             return n + 10
         self.encoding_test(f, [5], """
-            int_add %i0, $10, %i1
+            int_add %i0, $10 -> %i1
             int_return %i1
         """)
 
@@ -117,18 +117,20 @@
                 a -= 1
             return b
         self.encoding_test(f, [5, 6], """
-            int_copy %i0, %i2
-            int_copy %i1, %i3
+            int_copy %i0 -> %i2
+            int_copy %i1 -> %i3
             L1:
-            int_gt %i2, $0, %i4
+            int_gt %i2, $0 -> %i4
             goto_if_not %i4, L2
-            int_copy %i2, %i5
-            int_copy %i3, %i6
-            int_add %i6, %i5, %i7
-            int_sub %i5, $1, %i8
-            int_copy %i8, %i2
-            int_copy %i7, %i3
+            -live- L2
+            int_copy %i2 -> %i5
+            int_copy %i3 -> %i6
+            int_add %i6, %i5 -> %i7
+            int_sub %i5, $1 -> %i8
+            int_copy %i8 -> %i2
+            int_copy %i7 -> %i3
             goto L1
+            ---
             L2:
             int_return %i3
         """)
@@ -140,17 +142,19 @@
                 a -= 1
             return b
         self.encoding_test(f, [5, 6], """
-            int_copy %i0, %i2
-            int_copy %i1, %i3
+            int_copy %i0 -> %i2
+            int_copy %i1 -> %i3
             L1:
             goto_if_not_int_gt %i2, $0, L2
-            int_copy %i2, %i4
-            int_copy %i3, %i5
-            int_add %i5, %i4, %i6
-            int_sub %i4, $1, %i7
-            int_copy %i7, %i2
-            int_copy %i6, %i3
+            -live- L2
+            int_copy %i2 -> %i4
+            int_copy %i3 -> %i5
+            int_add %i5, %i4 -> %i6
+            int_sub %i4, $1 -> %i7
+            int_copy %i7 -> %i2
+            int_copy %i6 -> %i3
             goto L1
+            ---
             L2:
             int_return %i3
         """, transform=True)
@@ -159,10 +163,10 @@
         def f(i, f):
             return (i*5) + (f*0.25)
         self.encoding_test(f, [4, 7.5], """
-            int_mul %i0, $5, %i1
-            float_mul %f0, $0.25, %f1
-            cast_int_to_float %i1, %f2
-            float_add %f2, %f1, %f3
+            int_mul %i0, $5 -> %i1
+            float_mul %f0, $0.25 -> %f1
+            cast_int_to_float %i1 -> %f2
+            float_add %f2, %f1 -> %f3
             float_return %f3
         """)
 
@@ -180,7 +184,7 @@
         flattener = GraphFlattener(None, fake_regallocs())
         flattener.serialize_op(op)
         assert_format(flattener.ssarepr, """
-            residual_call_ir_f $12345, I[%i0, %i1], R[%r0, %r1], %f0
+            residual_call_ir_f $12345, I[%i0, %i1], R[%r0, %r1] -> %f0
         """)
 
     def test_same_as_removal(self):
@@ -188,7 +192,7 @@
             b = chr(a)
             return ord(b) + a
         self.encoding_test(f, [65], """
-            int_add %i0, %i0, %i1
+            int_add %i0, %i0 -> %i1
             int_return %i1
         """, transform=True)
 
@@ -210,15 +214,19 @@
             elif n == 7: return 1212
             else:        return 42
         self.encoding_test(f, [65], """
+            -live-
             int_guard_value %i0
             goto_if_not_int_eq %i0, $-5, L1
             int_return $12
+            ---
             L1:
             goto_if_not_int_eq %i0, $2, L2
             int_return $51
+            ---
             L2:
             goto_if_not_int_eq %i0, $7, L3
             int_return $1212
+            ---
             L3:
             int_return $42
         """)
@@ -233,18 +241,25 @@
             elif x == 6: return 54
             return -1
         self.encoding_test(f, [65], """
+            -live-
             switch %i0, <SwitchDictDescr 1:L1, 2:L2, 3:L3, 4:L4, 5:L5, 6:L6>
             int_return $-1
+            ---
             L1:
             int_return $61
+            ---
             L2:
             int_return $511
+            ---
             L3:
             int_return $-22
+            ---
             L4:
             int_return $81
+            ---
             L5:
             int_return $17
+            ---
             L6:
             int_return $54
         """)
@@ -267,12 +282,15 @@
             direct_call $<* fn g>, %i0
             catch_exception L1
             int_return $3
+            ---
             L1:
             goto_if_exception_mismatch $<* struct object_vtable>, L2
             int_return $1
+            ---
             L2:
             goto_if_exception_mismatch $<* struct object_vtable>, L3
             int_return $2
+            ---
             L3:
             reraise
         """)
@@ -295,15 +313,18 @@
                 return 4
 
         self.encoding_test(f, [65], """
-            G_residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+            residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+            -live-
             catch_exception L1
             int_return $4
+            ---
             L1:
             goto_if_exception_mismatch $<* struct object_vtable>, L2
-            last_exc_value %r0
-            ref_copy %r0, %r1
-            getfield_gc_i %r1, <Descr>, %i1
+            last_exc_value -> %r0
+            ref_copy %r0 -> %r1
+            getfield_gc_i %r1, <Descr> -> %i1
             int_return %i1
+            ---
             L2:
             int_return $3
         """, transform=True)
@@ -332,6 +353,7 @@
             direct_call $<* fn g>, %i0
             catch_exception L1
             void_return
+            ---
             L1:
             raise $<* struct object>
         """)
@@ -340,11 +362,13 @@
         def f(i):
             return not i
 
-        # note that 'goto_if_not_int_is_true' is actually the same thing
-        # as just 'goto_if_not'.
+        # note that 'goto_if_not_int_is_true' is not the same thing
+        # as just 'goto_if_not', because the last one expects a boolean
         self.encoding_test(f, [7], """
-            goto_if_not %i0, L1
+            goto_if_not_int_is_true %i0, L1
+            -live- L1
             int_return $False
+            ---
             L1:
             int_return $True
         """, transform=True)
@@ -360,15 +384,19 @@
             except ZeroDivisionError:
                 return -42
         self.encoding_test(f, [7, 2], """
-            G_residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+            -live-
             catch_exception L1
             int_return %i2
+            ---
             L1:
             goto_if_exception_mismatch $<* struct object_vtable>, L2
             int_return $42
+            ---
             L2:
             goto_if_exception_mismatch $<* struct object_vtable>, L3
             int_return $-42
+            ---
             L3:
             reraise
         """, transform=True)
@@ -383,16 +411,34 @@
                 return 42
         # XXX so far, this really produces a int_mod_ovf_zer...
         self.encoding_test(f, [7, 2], """
-            G_residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+            -live-
             catch_exception L1
             int_return %i2
+            ---
             L1:
             goto_if_exception_mismatch $<* struct object_vtable>, L2
             int_return $42
+            ---
             L2:
             reraise
         """, transform=True)
 
+    def test_simple_branch(self):
+        def f(n, m1, m2):
+            if n:
+                return m1
+            else:
+                return m2
+        self.encoding_test(f, [4, 5, 6], """
+            goto_if_not_int_is_true %i0, L1
+            -live- %i1, %i2, L1
+            int_return %i1
+            ---
+            L1:
+            int_return %i2
+        """, transform=True, liveness=True)
+
     def test_int_add_ovf(self):
         def f(i, j):
             try:
@@ -400,10 +446,11 @@
             except OverflowError:
                 return 42
         self.encoding_test(f, [7, 2], """
-            -live-
-            G_int_add_ovf %i0, %i1, %i2
+            int_add_ovf %i0, %i1 -> %i2
+            -live- %i2
             catch_exception L1
             int_return %i2
+            ---
             L1:
             int_return $42
         """, transform=True, liveness=True)
@@ -418,13 +465,14 @@
             except Exception:
                 return 42 + j
         self.encoding_test(f, [7, 2], """
-            -live- %i1
-            G_residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[], %i2
+            residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[] -> %i2
+            -live- %i1, %i2
             catch_exception L1
             int_return %i2
+            ---
             L1:
-            int_copy %i1, %i3
-            int_add %i3, $42, %i4
+            int_copy %i1 -> %i3
+            int_add %i3, $42 -> %i4
             int_return %i4
         """, transform=True, liveness=True)
 
@@ -438,7 +486,7 @@
             except Exception:
                 return 42 + j
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn cannot_raise>, <Descr>, I[%i0, %i1], R[], %i2
+            residual_call_ir_i $<* fn cannot_raise>, <Descr>, I[%i0, %i1], R[] -> %i2
             int_return %i2
         """, transform=True, liveness=True)
 
@@ -458,11 +506,12 @@
             myjitdriver.jit_merge_point(x=x, y=y)
             myjitdriver.can_enter_jit(x=y, y=x)
         self.encoding_test(f, [4, 5], """
-            G_int_guard_value %i0
+            int_guard_value %i0
+            -live- %i0, %i1
             jit_merge_point I[%i0], R[], F[], I[%i1], R[], F[]
             can_enter_jit
             void_return
-        """, transform=True)
+        """, transform=True, liveness=True)
 
     def test_keepalive(self):
         S = lltype.GcStruct('S')
@@ -475,9 +524,20 @@
             keepalive_until_here(q)
             return x
         self.encoding_test(f, [5], """
-            G_residual_call_r_r $<* fn g>, <Descr>, R[], %r0
-            G_residual_call_r_r $<* fn g>, <Descr>, R[], %r1
-            keepalive %r0
-            keepalive %r1
+            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+            -live-
+            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+            -live-
+            -live- %r0
+            -live- %r1
             int_return %i0
         """, transform=True)
+        self.encoding_test(f, [5], """
+            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+            -live- %i0, %r0
+            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+            -live- %i0, %r0, %r1
+            -live- %i0, %r0, %r1
+            -live- %i0, %r1
+            int_return %i0
+        """, transform=True, liveness=True)

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	Fri May 21 15:46:57 2010
@@ -59,11 +59,13 @@
         graph = self.make_graphs(f, [5, 6])[0]
         self.check_assembler(graph, """
             L1:
-            int_gt %i0, $0, %i2
+            int_gt %i0, $0 -> %i2
             goto_if_not %i2, L2
-            int_add %i1, %i0, %i1
-            int_sub %i0, $1, %i0
+            -live- L2
+            int_add %i1, %i0 -> %i1
+            int_sub %i0, $1 -> %i0
             goto L1
+            ---
             L2:
             int_return %i1
         """)
@@ -76,12 +78,14 @@
         graph = self.make_graphs(f, [5, 6])[0]
         self.check_assembler(graph, """
             L1:
-            int_gt %i0, $0, %i2
+            int_gt %i0, $0 -> %i2
             goto_if_not %i2, L2
+            -live- L2
             int_push %i1
-            int_copy %i0, %i1
-            int_pop %i0
+            int_copy %i0 -> %i1
+            int_pop -> %i0
             goto L1
+            ---
             L2:
             int_return %i1
         """)
@@ -94,11 +98,13 @@
         graph = self.make_graphs(f, [5, 6])[0]
         self.check_assembler(graph, """
             L1:
-            int_gt %i0, $0, %i0
+            int_gt %i0, $0 -> %i0
             goto_if_not %i0, L2
-            int_copy %i1, %i0
-            int_copy $2, %i1
+            -live- L2
+            int_copy %i1 -> %i0
+            int_copy $2 -> %i1
             goto L1
+            ---
             L2:
             int_return %i1
         """)
@@ -111,13 +117,15 @@
         graph = self.make_graphs(f, [5, 6, 7])[0]
         self.check_assembler(graph, """
             L1:
-            int_gt %i0, $0, %i3
+            int_gt %i0, $0 -> %i3
             goto_if_not %i3, L2
+            -live- L2
             int_push %i1
-            int_copy %i2, %i1
-            int_copy %i0, %i2
-            int_pop %i0
+            int_copy %i2 -> %i1
+            int_copy %i0 -> %i2
+            int_pop -> %i0
             goto L1
+            ---
             L2:
             int_return %i1
         """)
@@ -130,10 +138,12 @@
         graph = self.make_graphs(f, [5, 6, 7])[0]
         self.check_assembler(graph, """
             L1:
-            int_gt %i0, $0, %i3
+            int_gt %i0, $0 -> %i3
             goto_if_not %i3, L2
-            int_copy %i2, %i1
+            -live- L2
+            int_copy %i2 -> %i1
             goto L1
+            ---
             L2:
             int_return %i1
         """)
@@ -152,8 +162,8 @@
         block.closeblock(Link([v3], graph.returnblock))
         #
         self.check_assembler(graph, """
-            int_add %i0, $1, %i1
-            rescall I[%i0, %i1], %i0
+            int_add %i0, $1 -> %i1
+            rescall I[%i0, %i1] -> %i0
             int_return %i0
         """)
 
@@ -164,7 +174,8 @@
         v4 = Variable(); v4.concretetype = rclass.CLASSTYPE
         block = Block([])
         block.operations = [
-            SpaceOperation('G_res_call', [], v1),
+            SpaceOperation('res_call', [], v1),
+            SpaceOperation('-live-', [], None),
             ]
         graph = FunctionGraph('f', block, v4)
         exclink = Link([v2], graph.returnblock)
@@ -176,13 +187,16 @@
                          exclink)
         #
         self.check_assembler(graph, """
-            G_res_call %i0
+            res_call -> %i0
+            -live-
             catch_exception L1
             int_return %i0
+            ---
             L1:
             goto_if_exception_mismatch $123, L2
-            last_exception %i0
+            last_exception -> %i0
             int_return %i0
+            ---
             L2:
             reraise
         """)
@@ -203,8 +217,8 @@
         block.closeblock(Link([v3], graph.returnblock))
         #
         self.check_assembler(graph, """
-            int_add %i0, $1, %i1
-            rescall I[%i0, %i1], %i2
-            rescall I[%i0, %i1], %i0
+            int_add %i0, $1 -> %i1
+            rescall I[%i0, %i1] -> %i2
+            rescall I[%i0, %i1] -> %i0
             int_return %i0
         """)

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py	Fri May 21 15:46:57 2010
@@ -195,8 +195,9 @@
 
             if resulttype == 'i':
                 # argcode should be 'i' too
-                assert argcodes[next_argcode] == 'i'
-                next_argcode = next_argcode + 1
+                assert argcodes[next_argcode] == '>'
+                assert argcodes[next_argcode+1] == 'i'
+                next_argcode = next_argcode + 2
                 if lltype.typeOf(result) is lltype.Bool:
                     result = int(result)
                 assert lltype.typeOf(result) is lltype.Signed
@@ -204,15 +205,17 @@
                 position += 1
             elif resulttype == 'r':
                 # argcode should be 'r' too
-                assert argcodes[next_argcode] == 'r'
-                next_argcode = next_argcode + 1
+                assert argcodes[next_argcode] == '>'
+                assert argcodes[next_argcode+1] == 'r'
+                next_argcode = next_argcode + 2
                 assert lltype.typeOf(result) == llmemory.GCREF
                 self.registers_r[ord(code[position])] = result
                 position += 1
             elif resulttype == 'f':
                 # argcode should be 'f' too
-                assert argcodes[next_argcode] == 'f'
-                next_argcode = next_argcode + 1
+                assert argcodes[next_argcode] == '>'
+                assert argcodes[next_argcode+1] == 'f'
+                next_argcode = next_argcode + 2
                 assert lltype.typeOf(result) is lltype.Float
                 self.registers_f[ord(code[position])] = result
                 position += 1
@@ -979,16 +982,34 @@
 
     def _prepare_resume_from_failure(self, opnum):
         from pypy.jit.metainterp.resoperation import rop
-        if opnum == rop.GUARD_TRUE:     # a goto_if_not_xxx that jumps only now
+        #
+        if opnum == rop.GUARD_TRUE:
+            # Produced directly by some goto_if_not_xxx() opcode that did not
+            # jump, but which must now jump.  The pc is just after the opcode.
             self.position = self.jitcode.follow_jump(self.position)
-        elif opnum == rop.GUARD_FALSE:  # a goto_if_not that stops jumping
+        #
+        elif opnum == rop.GUARD_FALSE:
+            # Produced directly by some goto_if_not_xxx() opcode that jumped,
+            # but which must no longer jump.  The pc is just after the opcode.
             pass
-        elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
+        #
+        elif opnum == rop.GUARD_VALUE or opnum == rop.GUARD_CLASS:
+            # Produced by guard_class(), xxx_guard_value(), or a few other
+            # opcodes like switch().  The pc is at the start of the opcode
+            # (so it will be redone).
             pass
-        elif opnum == rop.GUARD_CLASS or opnum == rop.GUARD_VALUE:
+        #
+        elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
+            xxx
+        elif (opnum == rop.GUARD_NO_EXCEPTION or
+              opnum == rop.GUARD_EXCEPTION or
+              opnum == rop.GUARD_NOT_FORCED or
+              opnum == rop.GUARD_NO_OVERFLOW or
+              opnum == rop.GUARD_OVERFLOW):
             pass
         else:
-            raise NotImplementedError(opnum)
+            from pypy.jit.metainterp.resoperation import opname
+            raise NotImplementedError(opname[opnum])
 
     # connect the return of values from the called frame to the
     # 'xxx_call_yyy' instructions from the caller frame

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py	Fri May 21 15:46:57 2010
@@ -366,6 +366,8 @@
         except lltype.UninitializedMemoryAccess:
             return '<uninitialized string>'
 
+CONST_NULL = ConstPtr(ConstPtr.value)
+
 class ConstObj(Const):
     type = REF
     value = ootype.NULL

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	Fri May 21 15:46:57 2010
@@ -182,7 +182,6 @@
     for _opimpl in ['int_is_true', 'int_is_zero', 'int_neg', 'int_invert',
                     'cast_ptr_to_int', 'cast_float_to_int',
                     'cast_int_to_float', 'float_neg', 'float_abs',
-                    'ptr_iszero', 'ptr_nonzero',
                     ]:
         exec py.code.Source('''
             @arguments("box")
@@ -191,6 +190,14 @@
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     @arguments("box")
+    def opimpl_ptr_nonzero(self, box):
+        return self.execute(rop.PTR_NE, box, history.CONST_NULL)
+
+    @arguments("box")
+    def opimpl_ptr_iszero(self, box):
+        return self.execute(rop.PTR_EQ, box, history.CONST_NULL)
+
+    @arguments("box")
     def _opimpl_any_return(self, box):
         self.metainterp.finishframe(box)
 
@@ -252,13 +259,15 @@
         if not switchcase:
             self.pc = target
 
-    for _opimpl in ['int_is_zero', 'ptr_iszero', 'ptr_nonzero']:
-        exec py.code.Source('''
-            @arguments("box", "label")
-            def opimpl_goto_if_not_%s(self, box, target):
-                condbox = self.execute(rop.%s, box)
-                self.opimpl_goto_if_not(condbox, target)
-        ''' % (_opimpl, _opimpl.upper())).compile()
+    @arguments("box", "label")
+    def opimpl_goto_if_not_int_is_true(self, box, target):
+        condbox = self.execute(rop.INT_IS_TRUE, box)
+        self.opimpl_goto_if_not(condbox, target)
+
+    @arguments("box", "label")
+    def opimpl_goto_if_not_int_is_zero(self, box, target):
+        condbox = self.execute(rop.INT_IS_ZERO, box)
+        self.opimpl_goto_if_not(condbox, target)
 
     for _opimpl in ['int_lt', 'int_le', 'int_eq', 'int_ne', 'int_gt', 'int_ge',
                     'ptr_eq', 'ptr_ne']:
@@ -268,7 +277,29 @@
                 condbox = self.execute(rop.%s, b1, b2)
                 self.opimpl_goto_if_not(condbox, target)
         ''' % (_opimpl, _opimpl.upper())).compile()
-    
+
+    @arguments("box", "label")
+    def opimpl_goto_if_not_ptr_nonzero(self, box, target):
+        value = box.nonnull()
+        if value:
+            opnum = rop.GUARD_NONNULL
+        else:
+            opnum = rop.GUARD_ISNULL
+        self.generate_guard(opnum, box)
+        if not value:
+            self.pc = target
+
+    @arguments("box", "label")
+    def opimpl_goto_if_not_ptr_iszero(self, box, target):
+        value = box.nonnull()
+        if value:
+            opnum = rop.GUARD_NONNULL
+        else:
+            opnum = rop.GUARD_ISNULL
+        self.generate_guard(opnum, box)
+        if value:
+            self.pc = target
+
 ##    def follow_jump(self):
 ##        _op_goto_if_not = self.metainterp.staticdata._op_goto_if_not
 ##        assert ord(self.bytecode[self.pc]) == _op_goto_if_not
@@ -1003,6 +1034,9 @@
         self.indirectcalltargets = list(indirectcalltargets)
 
     def finish_setup(self, codewriter, optimizer=None):
+        from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
+        self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
+        #
         asm = codewriter.assembler
         self.setup_insns(asm.insns)
         self.setup_descrs(asm.descrs)
@@ -1012,9 +1046,6 @@
         RESULT = codewriter.portal_graph.getreturnvar().concretetype
         self.result_type = history.getkind(RESULT)
         #
-        from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
-        self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
-        #
         warmrunnerdesc = self.warmrunnerdesc
         if warmrunnerdesc is not None:
             self.num_green_args = warmrunnerdesc.num_green_args
@@ -1514,6 +1545,10 @@
             frame.pc = frame.jitcode.follow_jump(frame.pc)
         elif opnum == rop.GUARD_FALSE:     # a goto_if_not that stops jumping
             pass
+        elif opnum == rop.GUARD_VALUE or opnum == rop.GUARD_CLASS:
+            pass        # the pc is already set to the *start* of the opcode
+        elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
+            xxx #self.framestack[-1].ignore_next_guard_nullness(opnum)
         elif (opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION
               or opnum == rop.GUARD_NOT_FORCED):
             exception = self.cpu.grab_exc_value()
@@ -1523,13 +1558,13 @@
                 self.execute_did_not_raise()
             self.handle_possible_exception()
         elif opnum == rop.GUARD_NO_OVERFLOW:   # an overflow now detected
-            xxx #self.raise_overflow_error()
-        elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
-            xxx #self.framestack[-1].ignore_next_guard_nullness(opnum)
-        elif opnum == rop.GUARD_CLASS or opnum == rop.GUARD_VALUE:
+            self.execute_raised(OverflowError(), constant=True)
+            self.finishframe_exception()
+        elif opnum == rop.GUARD_OVERFLOW:      # no longer overflowing
             pass
         else:
-            raise NotImplementedError(opnum)
+            from pypy.jit.metainterp.resoperation import opname
+            raise NotImplementedError(opname[opnum])
 
     def compile(self, original_boxes, live_arg_boxes, start):
         num_green_args = self.staticdata.num_green_args

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py	Fri May 21 15:46:57 2010
@@ -183,8 +183,6 @@
     #
     'SAME_AS/1',      # gets a Const or a Box, turns it into another Box
     #
-    'PTR_ISZERO/1b',
-    'PTR_NONZERO/1b',
     'PTR_EQ/2b',
     'PTR_NE/2b',
     #



More information about the Pypy-commit mailing list