[pypy-svn] r74377 - in pypy/branch/blackhole-improvement/pypy/jit: backend/llgraph backend/test backend/x86 codewriter codewriter/test metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Wed May 5 11:23:25 CEST 2010


Author: arigo
Date: Wed May  5 11:23:22 2010
New Revision: 74377

Added:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py   (contents, props changed)
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/policy.py
      - copied, changed from r74271, pypy/branch/blackhole-improvement/pypy/jit/metainterp/policy.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py   (contents, props changed)
Removed:
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/policy.py
Modified:
   pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/test/runner_test.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
   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/liveness.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.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_liveness.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_codewriter.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
Log:
In-progress.  Start to write or copy code in codewriter/*
to handle more than one JitCode.


Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py	Wed May  5 11:23:22 2010
@@ -103,7 +103,6 @@
     'float_ge'        : (('float', 'float'), 'bool'),
     'float_neg'       : (('float',), 'float'),
     'float_abs'       : (('float',), 'float'),
-    'float_is_true'   : (('float',), 'bool'),
     'cast_float_to_int':(('float',), 'int'),
     'cast_int_to_float':(('int',), 'float'),
     'same_as'         : (('int',), 'int'),      # could also be ptr=>ptr

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/test/runner_test.py	Wed May  5 11:23:22 2010
@@ -1085,7 +1085,6 @@
                                            operator.truediv, no_zero_divison
         yield nan_and_infinity, rop.FLOAT_NEG, operator.neg, all_cases_unary
         yield nan_and_infinity, rop.FLOAT_ABS, abs,          all_cases_unary
-        yield nan_and_infinity, rop.FLOAT_IS_TRUE, bool,     all_cases_unary
         yield nan_and_infinity, rop.FLOAT_LT,  operator.lt,  all_cases_binary
         yield nan_and_infinity, rop.FLOAT_LE,  operator.le,  all_cases_binary
         yield nan_and_infinity, rop.FLOAT_EQ,  operator.eq,  all_cases_binary

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py	Wed May  5 11:23:22 2010
@@ -695,32 +695,6 @@
         # Following what gcc does: res = x & 0x7FFFFFFFFFFFFFFF
         self.mc.ANDPD(arglocs[0], self.loc_float_const_abs)
 
-    def genop_guard_float_is_true(self, op, guard_op, addr, arglocs, resloc):
-        guard_opnum = guard_op.opnum
-        loc0, loc1 = arglocs
-        self.mc.XORPD(loc0, loc0)
-        self.mc.UCOMISD(loc0, loc1)
-        mc = self.mc._mc
-        if guard_opnum == rop.GUARD_TRUE:
-            mc.JP(rel8(6))
-            mc.JZ(rel32(addr))
-            return mc.tell() - 4
-        else:
-            mc.JP(rel8(2))
-            mc.JZ(rel8(5))
-            return self.implement_guard(addr, mc.JMP)
-
-    def genop_float_is_true(self, op, arglocs, resloc):
-        loc0, loc1 = arglocs
-        self.mc.XORPD(loc0, loc0)
-        self.mc.UCOMISD(loc0, loc1)
-        rl = resloc.lowest8bits()
-        rh = resloc.higher8bits()
-        self.mc.SETNE(rl)
-        self.mc.SETP(rh)
-        self.mc.OR(rl, rh)
-        self.mc.MOVZX(resloc, rl)
-
     def genop_cast_float_to_int(self, op, arglocs, resloc):
         self.mc.CVTTSD2SI(resloc, arglocs[0])
 

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	Wed May  5 11:23:22 2010
@@ -42,31 +42,39 @@
     def num_regs_f(self):
         return self.num_regs_encoded & 0x1FF
 
+    def has_liveness_info(self, pc):
+        return pc in self.liveness
+
     def enumerate_live_vars(self, pc, callback, arg,
                             registers_i, registers_r, registers_f):
         # 'pc' gives a position in this bytecode.  This invokes
         # 'callback' for each variable that is live across the
         # instruction which starts at 'pc'.  (It excludes the arguments
         # of that instruction which are no longer used afterwards, and
-        # also the return value of that instruction.)  More precisely,
-        # this invokes 'callback(arg, box)' where 'box' comes from one
-        # of the three lists of registers.  If the callback returns a
-        # box, then it is stored back.
+        # excludes the return value of that instruction.)  More precisely,
+        # this invokes 'callback(arg, box, index)' where 'box' comes from one
+        # of the three lists of registers and 'index' is 0, 1, 2...
+        # If the callback returns a box, then it is stored back.
         if not we_are_translated() and pc not in self.liveness:
             self._missing_liveness(pc)
         live_i, live_r, live_f = self.liveness[pc]    # XXX compactify!!
+        index = 0
         for c in live_i:
-            newbox = callback(arg, registers_i[ord(c)])
+            newbox = callback(arg, registers_i[ord(c)], index)
+            index += 1
             if newbox is not None:
                 registers_i[ord(c)] = newbox
         for c in live_r:
-            newbox = callback(arg, registers_r[ord(c)])
+            newbox = callback(arg, registers_r[ord(c)], index)
+            index += 1
             if newbox is not None:
                 registers_r[ord(c)] = newbox
         for c in live_f:
-            newbox = callback(arg, registers_f[ord(c)])
+            newbox = callback(arg, registers_f[ord(c)], index)
+            index += 1
             if newbox is not None:
                 registers_f[ord(c)] = newbox
+        return index
     enumerate_live_vars._annspecialcase_ = 'specialize:arg(2)'
 
     def _live_vars(self, pc):
@@ -76,7 +84,7 @@
                 self.kind = kind
             def __getitem__(self, index):
                 return '%%%s%d' % (self.kind, index)
-        def callback(lst, reg):
+        def callback(lst, reg, index):
             lst.append(reg)
         lst = []
         self.enumerate_live_vars(pc, callback, lst,
@@ -221,7 +229,9 @@
             else:
                 raise NotImplementedError(x)
         #
-        key = insn[0] + '/' + ''.join(argcodes)
+        opname = insn[0]
+        if opname.startswith('G_'): opname = opname[2:]
+        key = opname + '/' + ''.join(argcodes)
         num = self.insns.setdefault(key, len(self.insns))
         self.code[startposition] = chr(num)
 

Added: pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py
==============================================================================
--- (empty file)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py	Wed May  5 11:23:22 2010
@@ -0,0 +1,113 @@
+#
+# Contains the logic to decide, based on the policy, which graphs
+# to transform to JitCodes or not.
+#
+
+from pypy.jit.codewriter import support
+from pypy.translator.simplify import get_funcobj
+
+
+class CallControl(object):
+
+    def __init__(self, rtyper=None, portal_runner_obj=None):
+        self.rtyper = rtyper
+        self.portal_runner_obj = portal_runner_obj
+
+    def find_all_graphs(self, portal_graph, policy):
+        def is_candidate(graph):
+            return policy.look_inside_graph(graph)
+        
+        todo = [portal_graph]
+        candidate_graphs = set(todo)
+
+        def callers():
+            graph = top_graph
+            print graph
+            while graph in coming_from:
+                graph = coming_from[graph]
+                print '<-', graph
+        coming_from = {}
+
+        while todo:
+            top_graph = todo.pop()
+            for _, op in top_graph.iterblockops():
+                if op.opname not in ("direct_call", "indirect_call", "oosend"):
+                    continue
+                kind = self.guess_call_kind(op, is_candidate)
+                # use callers() to view the calling chain in pdb
+                if kind != "regular":
+                    continue
+                for graph in self.graphs_from(op, is_candidate):
+                    if graph in candidate_graphs:
+                        continue
+                    assert is_candidate(graph)
+                    todo.append(graph)
+                    candidate_graphs.add(graph)
+                    coming_from[graph] = top_graph
+        self.candidate_graphs = candidate_graphs
+        return candidate_graphs
+
+    def graphs_from(self, op, is_candidate=None):
+        if is_candidate is None:
+            is_candidate = self.is_candidate
+        if op.opname == 'direct_call':
+            funcobj = get_funcobj(op.args[0].value)
+            graph = funcobj.graph
+            if is_candidate(graph):
+                return [graph]     # common case: look inside this graph
+        else:
+            assert op.opname in ('indirect_call', 'oosend')
+            if op.opname == 'indirect_call':
+                graphs = op.args[-1].value
+            else:
+                v_obj = op.args[1].concretetype
+                graphs = v_obj._lookup_graphs(op.args[0].value)
+            if graphs is not None:
+                result = []
+                for graph in graphs:
+                    if is_candidate(graph):
+                        result.append(graph)
+                if result:
+                    return result  # common case: look inside these graphs,
+                                   # and ignore the others if there are any
+            else:
+                # special case: handle the indirect call that goes to
+                # the 'instantiate' methods.  This check is a bit imprecise
+                # but it's not too bad if we mistake a random indirect call
+                # for the one to 'instantiate'.
+                from pypy.rpython.lltypesystem import rclass
+                CALLTYPE = op.args[0].concretetype
+                if (op.opname == 'indirect_call' and len(op.args) == 2 and
+                    CALLTYPE == rclass.OBJECT_VTABLE.instantiate):
+                    return list(self._graphs_of_all_instantiate())
+        # residual call case: we don't need to look into any graph
+        return None
+
+    def _graphs_of_all_instantiate(self):
+        for vtable in self.rtyper.lltype2vtable.values():
+            if vtable.instantiate:
+                yield vtable.instantiate._obj.graph
+
+    def guess_call_kind(self, op, is_candidate=None):
+        if op.opname == 'direct_call':
+            funcptr = op.args[0].value
+            funcobj = get_funcobj(funcptr)
+            if getattr(funcobj, 'graph', None) is None:
+                return 'residual'
+            if funcobj is self.portal_runner_obj:
+                return 'recursive'
+            targetgraph = funcobj.graph
+            if (hasattr(targetgraph, 'func') and
+                hasattr(targetgraph.func, 'oopspec')):
+                return 'builtin'
+        elif op.opname == 'oosend':
+            SELFTYPE, methname, opargs = support.decompose_oosend(op)
+            if SELFTYPE.oopspec_name is not None:
+                return 'builtin'
+        if self.graphs_from(op, is_candidate) is None:
+            return 'residual'
+        return 'regular'
+
+    def is_candidate(self, graph):
+        # used only after find_all_graphs()
+        return graph in self.candidate_graphs

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	Wed May  5 11:23:22 2010
@@ -165,7 +165,7 @@
             for link in block.exits[1:]:
                 if (link.exitcase is Exception or
                     (link.exitcase is OverflowError and
-                     lastopname.startswith('int_') and
+                     lastopname.startswith('G_int_') and
                      lastopname.endswith('_ovf'))):
                     # this link captures all exceptions
                     self.make_exception_link(link)

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	Wed May  5 11:23:22 2010
@@ -74,7 +74,7 @@
             print "Got:      " + asm
             print "Expected: " + exp
             lgt = 0
-            for i in range(len(asm)):
+            for i in range(min(len(asm), len(exp))):
                 if exp[i] == asm[i]:
                     lgt += 1
                 else:
@@ -82,3 +82,45 @@
             print "          " + " " * lgt + "^^^^"
             raise AssertionError
     assert len(asmlines) == len(explines)
+
+def unformat_assembler(text, registers=None):
+    # XXX limited to simple assembler right now
+    #
+    def unformat_arg(s):
+        if s[0] == '%':
+            try:
+                return registers[s]
+            except KeyError:
+                num = int(s[2:])
+                if s[1] == 'i': reg = Register('int', num)
+                elif s[1] == 'r': reg = Register('ref', num)
+                elif s[1] == 'f': reg = Register('float', num)
+                else: raise AssertionError("bad register type")
+                registers[s] = reg
+                return reg
+        elif s[0] == '$':
+            intvalue = int(s[1:])
+            return Constant(intvalue, lltype.Signed)
+        elif s[0] == 'L':
+            return TLabel(s)
+        else:
+            raise AssertionError("unsupported argument: %r" % (s,))
+    #
+    if registers is None:
+        registers = {}
+    ssarepr = SSARepr('test')
+    for line in text.splitlines():
+        line = line.strip()
+        if not line:
+            continue
+        if line.startswith('L') and line.endswith(':'):
+            ssarepr.insns.append((Label(line[:-1]),))
+        else:
+            try:
+                opname, line = line.split(None, 1)
+            except ValueError:
+                opname, line = line, ''
+            line = [s.strip() for s in line.split(',')]
+            insn = [opname] + [unformat_arg(s) for s in line if s]
+            ssarepr.insns.append(tuple(insn))
+    return ssarepr

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	Wed May  5 11:23:22 2010
@@ -121,15 +121,46 @@
             return rewrite(self, op)
 
     def rewrite_op_same_as(self, op): raise NoOp
-    def rewrite_op_cast_int_to_char(self, op): raise NoOp
-    def rewrite_op_cast_int_to_unichar(self, op): raise NoOp
+    def rewrite_op_cast_pointer(self, op): raise NoOp
+    def rewrite_op_cast_primitive(self, op): raise NoOp
+    def rewrite_op_cast_bool_to_int(self, op): raise NoOp
+    def rewrite_op_cast_bool_to_uint(self, op): raise NoOp
     def rewrite_op_cast_char_to_int(self, op): raise NoOp
     def rewrite_op_cast_unichar_to_int(self, op): raise NoOp
-    def rewrite_op_cast_bool_to_int(self, op): raise NoOp
-    def rewrite_op_cast_pointer(self, op): raise NoOp
+    def rewrite_op_cast_int_to_char(self, op): raise NoOp
+    def rewrite_op_cast_int_to_unichar(self, op): raise NoOp
     def rewrite_op_cast_int_to_uint(self, op): raise NoOp
     def rewrite_op_cast_uint_to_int(self, op): raise NoOp
 
+    def _rewrite_symmetric(self, op):
+        """Rewrite 'c1+v2' into 'v2+c1' in an attempt to avoid generating
+        too many variants of the bytecode."""
+        if (isinstance(op.args[0], Constant) and
+            isinstance(op.args[1], Variable)):
+            reversename = {'int_lt': 'int_gt',
+                           'int_le': 'int_ge',
+                           'int_gt': 'int_lt',
+                           'int_ge': 'int_le',
+                           'float_lt': 'float_gt',
+                           'float_le': 'float_ge',
+                           'float_gt': 'float_lt',
+                           'float_ge': 'float_le',
+                           }.get(op.opname, op.opname)
+            return SpaceOperation(reversename,
+                                  [op.args[1], op.args[0]] + op.args[2:],
+                                  op.result)
+        else:
+            return op
+
+    rewrite_op_int_add = _rewrite_symmetric
+    rewrite_op_int_mul = _rewrite_symmetric
+    rewrite_op_int_and = _rewrite_symmetric
+    rewrite_op_int_or  = _rewrite_symmetric
+    rewrite_op_int_xor = _rewrite_symmetric
+
+    rewrite_op_G_int_add_ovf = _rewrite_symmetric
+    rewrite_op_G_int_mul_ovf = _rewrite_symmetric
+
     def rewrite_op_direct_call(self, op):
         """Turn 'i0 = direct_call(fn, i1, i2, ref1, ref2)'
            into e.g. 'i0 = residual_call_ir_i(fn, [i1, i2], [ref1, ref2])'.
@@ -150,7 +181,7 @@
         FUNC = op.args[0].concretetype.TO
         NONVOIDARGS = tuple([ARG for ARG in FUNC.ARGS if ARG != lltype.Void])
         calldescr = self.cpu.calldescrof(FUNC, NONVOIDARGS, FUNC.RESULT)
-        return SpaceOperation('residual_call_%s_%s' % (kinds, reskind),
+        return SpaceOperation('G_residual_call_%s_%s' % (kinds, reskind),
                               [op.args[0], calldescr] + sublists,
                               op.result)
 
@@ -184,7 +215,7 @@
     rewrite_op_int_mod_ovf_zer = _do_builtin_call
     rewrite_op_int_mod_ovf     = _do_builtin_call
     rewrite_op_int_mod_zer     = _do_builtin_call
-
+    rewrite_op_int_lshift_ovf  = _do_builtin_call
     rewrite_op_gc_identityhash = _do_builtin_call
 
     def rewrite_op_hint(self, op):
@@ -192,7 +223,9 @@
         if hints.get('promote') and op.args[0].concretetype is not lltype.Void:
             assert op.args[0].concretetype != lltype.Ptr(rstr.STR)
             kind = getkind(op.args[0].concretetype)
-            return SpaceOperation('%s_guard_value' % kind,
+            # note: the 'G_' prefix tells that the operation might generate
+            # a guard in pyjitpl (see liveness.py)
+            return SpaceOperation('G_%s_guard_value' % kind,
                                   [op.args[0]], op.result)
         else:
             log.WARNING('ignoring hint %r at %r' % (hints, self.graph))
@@ -308,7 +341,9 @@
                 op.args[0].concretetype.TO._hints.get('typeptr'))
 
     def handle_getfield_typeptr(self, op):
-        return SpaceOperation('guard_class', [op.args[0]], op.result)
+        # note: the 'G_' prefix tells that the operation might generate
+        # a guard in pyjitpl (see liveness.py)
+        return SpaceOperation('G_guard_class', [op.args[0]], op.result)
 
     def rewrite_op_malloc(self, op):
         assert op.args[1].value == {'flavor': 'gc'}
@@ -343,7 +378,7 @@
         elif isinstance(arg1, Constant) and not arg1.value:
             return SpaceOperation(opname, [arg0], op.result)
         else:
-            return op
+            return self._rewrite_symmetric(op)
 
     def _is_gc(self, v):
         return v.concretetype.TO._gckind == 'gc'
@@ -381,14 +416,69 @@
         else:
             raise NoOp
 
+    # ----------
+    # Renames, from the _old opname to the _new one.
+    # The new operation is optionally further processed by rewrite_operation().
     for _old, _new in [('bool_not', 'int_is_zero'),
                        ('cast_bool_to_float', 'cast_int_to_float'),
+                       ('cast_uint_to_float', 'cast_int_to_float'),
+                       ('cast_float_to_uint', 'cast_float_to_int'),
+
+                       ('int_add_ovf',        'G_int_add_ovf'),
+                       ('int_add_nonneg_ovf', 'G_int_add_ovf'),
+                       ('int_sub_ovf',        'G_int_sub_ovf'),
+                       ('int_mul_ovf',        'G_int_mul_ovf'),
+
+                       ('char_lt', 'int_lt'),
+                       ('char_le', 'int_le'),
+                       ('char_eq', 'int_eq'),
+                       ('char_ne', 'int_ne'),
+                       ('char_gt', 'int_gt'),
+                       ('char_ge', 'int_ge'),
+                       ('unichar_eq', 'int_eq'),
+                       ('unichar_ne', 'int_ne'),
+
+                       ('uint_is_true', 'int_is_true'),
+                       ('uint_invert', 'int_invert'),
+                       ('uint_add', 'int_add'),
+                       ('uint_sub', 'int_sub'),
+                       ('uint_mul', 'int_mul'),
+                       ('uint_floordiv', 'int_floordiv'),
+                       ('uint_floordiv_zer', 'int_floordiv_zer'),
+                       ('uint_mod', 'int_mod'),
+                       ('uint_mod_zer', 'int_mod_zer'),
+                       ('uint_lt', 'int_lt'),
+                       ('uint_le', 'int_le'),
+                       ('uint_eq', 'int_eq'),
+                       ('uint_ne', 'int_ne'),
+                       ('uint_gt', 'int_gt'),
+                       ('uint_ge', 'int_ge'),
+                       ('uint_and', 'int_and'),
+                       ('uint_or', 'int_or'),
+                       ('uint_lshift', 'int_lshift'),
+                       ('uint_rshift', 'int_rshift'),
+                       ('uint_xor', 'int_xor'),
+
+                       
                        ]:
         exec py.code.Source('''
             def rewrite_op_%s(self, op):
-                return SpaceOperation(%r, op.args, op.result)
+                op1 = SpaceOperation(%r, op.args, op.result)
+                return self.rewrite_operation(op1)
         ''' % (_old, _new)).compile()
 
+    def rewrite_op_int_neg_ovf(self, op):
+        op1 = SpaceOperation('int_sub_ovf',
+                             [Constant(0, lltype.Signed), op.args[0]],
+                             op.result)
+        return self.rewrite_operation(op1)
+
+    def rewrite_op_float_is_true(self, op):
+        op1 = SpaceOperation('float_ne',
+                             [op.args[0], Constant(0.0, lltype.Float)],
+                             op.result)
+        return self.rewrite_operation(op1)
+
 # ____________________________________________________________
 
 def _with_prefix(prefix):

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py	Wed May  5 11:23:22 2010
@@ -1,50 +1,37 @@
-import re
-from pypy.objspace.flow.model import Variable, SpaceOperation
+from pypy.objspace.flow.model import Variable, SpaceOperation, c_last_exception
 
 
-def compile_re(opnames):
-    return re.compile('|'.join(opnames))
-
-# List of instruction prefixes that might need the liveness information
-# (they are the ones that can end up in generate_guard() in pyjitpl.py).
-# Note that the goto_if_not_* operations are not present in the control
-# flow graph format; their liveness information is attached by setting
-# 'switches_require_liveness' to True.
-DEFAULT_OPNAMES_REQUIRING_LIVENESS = [
-    'residual_call_',
-    '(int|ref|float)_guard_value',
-    'guard_class',
-    'int_(add|sub|mul)_ovf',
-    ]
+# Some instruction require liveness information (the ones that can end up
+# in generate_guard() in pyjitpl.py); jitter.py prefixes these opnames
+# with a 'G_'.  Additionally, boolean and general switches in the flow graph
+# will turn in 'goto_if_not_*' operations, which also require liveness info.
 
 # ____________________________________________________________
 
-def compute_liveness(graph,
-                     switches_require_liveness = True,
-                     opnames_requiring_liveness =
-                         compile_re(DEFAULT_OPNAMES_REQUIRING_LIVENESS)):
-    if isinstance(opnames_requiring_liveness, list):
-        opnames_requiring_liveness = compile_re(opnames_requiring_liveness)
+def compute_liveness(graph, switches_require_liveness=True):
     for block in graph.iterblocks():
         num_operations = len(block.operations)
         alive = set()
         for link in block.exits:
             for v in link.args:
-                alive.add(v)
-        if switches_require_liveness and len(block.exits) > 1:
-            block.operations.append(_livespaceop(alive))
+                if (v is not link.last_exception and
+                    v is not link.last_exc_value):
+                    alive.add(v)
+        if switches_require_liveness:
+            if len(block.exits) > 1 and block.exitswitch != c_last_exception:
+                block.operations.append(_livespaceop(alive))
         if isinstance(block.exitswitch, tuple):
             for v in block.exitswitch[1:]:
                 alive.add(v)
         else:
-            alive.add(v)
+            alive.add(block.exitswitch)
         for i in range(num_operations-1, -1, -1):
             op = block.operations[i]
             try:
                 alive.remove(op.result)
             except KeyError:
                 pass
-            if opnames_requiring_liveness.match(op.opname):
+            if op.opname.startswith('G_'):
                 block.operations.insert(i, _livespaceop(alive))
             for v in op.args:
                 alive.add(v)

Copied: pypy/branch/blackhole-improvement/pypy/jit/codewriter/policy.py (from r74271, pypy/branch/blackhole-improvement/pypy/jit/metainterp/policy.py)
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/policy.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/policy.py	Wed May  5 11:23:22 2010
@@ -3,6 +3,12 @@
 from pypy.rpython.lltypesystem import lltype, rclass
 from pypy.tool.udir import udir
 
+import py, sys
+from pypy.tool.ansi_print import ansi_log
+log = py.log.Producer('jitcodewriter')
+py.log.setconsumer('jitcodewriter', ansi_log)
+
+
 class JitPolicy(object):
     def __init__(self):
         self.unsafe_loopy_graphs = set()
@@ -40,9 +46,6 @@
         # string builder interface
         if mod == 'pypy.rpython.lltypesystem.rbuilder':
             return True
-        # rweakvaluedict implementation
-        if mod == 'pypy.rlib.rweakrefimpl':
-            return True
         
         return False
 
@@ -76,7 +79,6 @@
                     getkind(v.concretetype, supports_floats)
                 getkind(op.result.concretetype, supports_floats)
     except NotImplementedError, e:
-        from pypy.jit.metainterp.codewriter import log
         log.WARNING('%s, ignoring graph' % (e,))
         log.WARNING('  %s' % (graph,))
         return True

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	Wed May  5 11:23:22 2010
@@ -157,6 +157,9 @@
 def _ll_2_int_mod_zer(x, y):
     return llop.int_mod_zer(lltype.Signed, x, y)
 
+def _ll_2_int_lshift_ovf(x, y):
+    return llop.int_lshift_ovf(lltype.Signed, x, y)
+
 
 class LLtypeHelpers:
 

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	Wed May  5 11:23:22 2010
@@ -161,15 +161,15 @@
     i3, i4, i5 = Register('int', 3), Register('int', 4), Register('int', 5)
     ssarepr.insns = [
         ('-live-', i0),
-        ('int_add', i0, Constant(10, lltype.Signed), i1),
+        ('G_int_add', i0, Constant(10, lltype.Signed), i1),
         ('-live-', i0, i1),
-        ('int_add', i0, Constant(3, lltype.Signed), i2),
+        ('G_int_add', i0, Constant(3, lltype.Signed), i2),
         ('-live-', i0),
-        ('int_mul', i1, i2, i3),
+        ('G_int_mul', i1, i2, i3),
         ('-live-', i3),
-        ('int_add', i0, Constant(6, lltype.Signed), i4),
+        ('G_int_add', i0, Constant(6, lltype.Signed), i4),
         ('-live-',),
-        ('int_mul', i3, i4, i5),
+        ('G_int_mul', i3, i4, i5),
         ('int_return', i5),
         ]
     assembler = Assembler()

Added: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py
==============================================================================
--- (empty file)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py	Wed May  5 11:23:22 2010
@@ -0,0 +1,208 @@
+from pypy.objspace.flow.model import SpaceOperation, Constant, Variable
+from pypy.rpython.lltypesystem import lltype
+from pypy.translator.unsimplify import varoftype
+from pypy.rlib import jit
+from pypy.jit.codewriter.call import CallControl
+from pypy.jit.codewriter import support
+from pypy.jit.codewriter.policy import JitPolicy
+
+
+def test_graphs_from_direct_call():
+    cc = CallControl()
+    F = lltype.FuncType([], lltype.Signed)
+    f = lltype.functionptr(F, 'f', graph='fgraph')
+    v = varoftype(lltype.Signed)
+    op = SpaceOperation('direct_call', [Constant(f, lltype.Ptr(F))], v)
+    #
+    lst = cc.graphs_from(op, {}.__contains__)
+    assert lst is None     # residual call
+    #
+    lst = cc.graphs_from(op, {'fgraph': True}.__contains__)
+    assert lst == ['fgraph']     # normal call
+
+def test_graphs_from_indirect_call():
+    cc = CallControl()
+    F = lltype.FuncType([], lltype.Signed)
+    v = varoftype(lltype.Signed)
+    graphlst = ['f1graph', 'f2graph']
+    op = SpaceOperation('indirect_call', [varoftype(lltype.Ptr(F)),
+                                          Constant(graphlst, lltype.Void)], v)
+    #
+    lst = cc.graphs_from(op, {'f1graph': True, 'f2graph': True}.__contains__)
+    assert lst == ['f1graph', 'f2graph']     # normal indirect call
+    #
+    lst = cc.graphs_from(op, {'f1graph': True}.__contains__)
+    assert lst == ['f1graph']     # indirect call, look only inside some graphs
+    #
+    lst = cc.graphs_from(op, {}.__contains__)
+    assert lst is None            # indirect call, don't look inside any graph
+
+def test_graphs_from_no_target():
+    cc = CallControl()
+    F = lltype.FuncType([], lltype.Signed)
+    v = varoftype(lltype.Signed)
+    op = SpaceOperation('indirect_call', [varoftype(lltype.Ptr(F)),
+                                          Constant(None, lltype.Void)], v)
+    lst = cc.graphs_from(op, {}.__contains__)
+    assert lst is None
+
+# ____________________________________________________________
+
+def test_find_all_graphs():
+    def f(x):
+        if x < 0:
+            return f(-x)
+        return x + 1
+    @jit.purefunction
+    def g(x):
+        return x + 2
+    @jit.dont_look_inside
+    def h(x):
+        return x + 3
+    def i(x):
+        return f(x) * g(x) * h(x)
+
+    rtyper = support.annotate(i, [7])
+    cc = CallControl()
+    jitpolicy = JitPolicy()
+    res = cc.find_all_graphs(rtyper.annotator.translator.graphs[0],
+                             jitpolicy)
+    translator = rtyper.annotator.translator
+
+    funcs = set([graph.func for graph in res])
+    assert funcs == set([i, f])
+
+def test_find_all_graphs_without_floats():
+    def g(x):
+        return int(x * 12.5)
+    def f(x):
+        return g(x) + 1
+    rtyper = support.annotate(f, [7])
+    cc = CallControl()
+    jitpolicy = JitPolicy()
+    jitpolicy.set_supports_floats(True)
+    translator = rtyper.annotator.translator
+    res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
+    funcs = set([graph.func for graph in res])
+    assert funcs == set([f, g])
+
+    cc = CallControl()
+    jitpolicy.set_supports_floats(False)
+    res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
+    funcs = [graph.func for graph in res]
+    assert funcs == [f]
+
+def test_find_all_graphs_loops():
+    def g(x):
+        i = 0
+        while i < x:
+            i += 1
+        return i
+    @jit.unroll_safe
+    def h(x):
+        i = 0
+        while i < x:
+            i += 1
+        return i
+
+    def f(x):
+        i = 0
+        while i < x*x:
+            i += g(x) + h(x)
+        return i
+
+    rtyper = support.annotate(f, [7])
+    cc = CallControl()
+    jitpolicy = JitPolicy()
+    translator = rtyper.annotator.translator
+    res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
+    funcs = set([graph.func for graph in res])
+    assert funcs == set([f, h])
+
+def test_unroll_safe_and_inline():
+    @jit.unroll_safe
+    def h(x):
+        i = 0
+        while i < x:
+            i += 1
+        return i
+    h._always_inline_ = True
+
+    def g(x):
+        return h(x)
+
+    rtyper = support.annotate(g, [7])
+    cc = CallControl()
+    jitpolicy = JitPolicy()
+    translator = rtyper.annotator.translator
+    res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
+    funcs = set([graph.func for graph in res])
+    assert funcs == set([g, h])
+
+def test_find_all_graphs_str_join():
+    def i(x, y):
+        return "hello".join([str(x), str(y), "bye"])
+
+    rtyper = support.annotate(i, [7, 100])
+    cc = CallControl()
+    jitpolicy = JitPolicy()
+    translator = rtyper.annotator.translator
+    # does not explode
+    cc.find_all_graphs(translator.graphs[0], jitpolicy)
+
+# ____________________________________________________________
+
+def test_guess_call_kind_and_calls_from_graphs():
+    class portal_runner_obj:
+        graph = object()
+    g = object()
+    g1 = object()
+    cc = CallControl(portal_runner_obj=portal_runner_obj)
+    cc.candidate_graphs = [g, g1]
+
+    op = SpaceOperation('direct_call', [Constant(portal_runner_obj)],
+                        Variable())
+    assert cc.guess_call_kind(op) == 'recursive'
+
+    op = SpaceOperation('direct_call', [Constant(object())],
+                        Variable())
+    assert cc.guess_call_kind(op) == 'residual'        
+
+    class funcptr:
+        class graph:
+            class func:
+                oopspec = "spec"
+    op = SpaceOperation('direct_call', [Constant(funcptr)],
+                        Variable())
+    assert cc.guess_call_kind(op) == 'builtin'
+
+    class funcptr:
+        graph = g
+    op = SpaceOperation('direct_call', [Constant(funcptr)],
+                        Variable())
+    res = cc.graphs_from(op)
+    assert res == [g]        
+    assert cc.guess_call_kind(op) == 'regular'
+
+    class funcptr:
+        graph = object()
+    op = SpaceOperation('direct_call', [Constant(funcptr)],
+                        Variable())
+    res = cc.graphs_from(op)
+    assert res is None        
+    assert cc.guess_call_kind(op) == 'residual'
+
+    h = object()
+    op = SpaceOperation('indirect_call', [Variable(),
+                                          Constant([g, g1, h])],
+                        Variable())
+    res = cc.graphs_from(op)
+    assert res == [g, g1]
+    assert cc.guess_call_kind(op) == 'regular'
+
+    op = SpaceOperation('indirect_call', [Variable(),
+                                          Constant([h])],
+                        Variable())
+    res = cc.graphs_from(op)
+    assert res is None
+    assert cc.guess_call_kind(op) == 'residual'        

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	Wed May  5 11:23:22 2010
@@ -8,6 +8,7 @@
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
 from pypy.translator.unsimplify import varoftype
 from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib.jit import dont_look_inside
 
 
 class FakeRegAlloc:
@@ -261,6 +262,7 @@
     def test_exc_exitswitch_2(self):
         class FooError(Exception):
             pass
+        @dont_look_inside
         def g(i):
             FooError().num = 1
             FooError().num = 2
@@ -275,7 +277,7 @@
                 return 4
 
         self.encoding_test(f, [65], """
-            residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+            G_residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
             catch_exception L1
             int_return $4
             L1:
@@ -340,7 +342,7 @@
             except ZeroDivisionError:
                 return -42
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            G_residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
             catch_exception L1
             int_return %i2
             L1:
@@ -363,7 +365,7 @@
                 return 42
         # XXX so far, this really produces a int_mod_ovf_zer...
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            G_residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
             catch_exception L1
             int_return %i2
             L1:
@@ -380,10 +382,44 @@
             except OverflowError:
                 return 42
         self.encoding_test(f, [7, 2], """
-            int_add_ovf %i0, %i1, %i2
-            -live- %i2
+            -live-
+            G_int_add_ovf %i0, %i1, %i2
             catch_exception L1
             int_return %i2
             L1:
             int_return $42
         """, transform=True, liveness=True)
+
+    def test_residual_call_raising(self):
+        @dont_look_inside
+        def g(i, j):
+            return ovfcheck(i + j)
+        def f(i, j):
+            try:
+                return g(i, j)
+            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
+            catch_exception L1
+            int_return %i2
+            L1:
+            int_copy %i1, %i3
+            int_add %i3, $42, %i4
+            int_return %i4
+        """, transform=True, liveness=True)
+
+    def test_residual_call_nonraising(self):
+        @dont_look_inside
+        def g(i, j):
+            return i + j
+        def f(i, j):
+            try:
+                return g(i, j)
+            except Exception:
+                return 42 + j
+        self.encoding_test(f, [7, 2], """
+            residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[], %i2
+            int_return %i2
+        """, transform=True, liveness=True)

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	Wed May  5 11:23:22 2010
@@ -1,6 +1,6 @@
 import py
 from pypy.objspace.flow.model import Constant
-from pypy.jit.codewriter.format import format_assembler
+from pypy.jit.codewriter.format import format_assembler, unformat_assembler
 from pypy.jit.codewriter.flatten import Label, TLabel, SSARepr, Register
 from pypy.jit.codewriter.flatten import ListOfKind
 from pypy.jit.metainterp.history import AbstractDescr
@@ -96,3 +96,41 @@
         foobar hi_there!
     """
     assert asm == str(py.code.Source(expected)).strip() + '\n'
+
+def test_unformat_assembler_simple():
+    input = """
+        int_add %i0, %i1, %i2
+        int_return %i2
+    """
+    regs = {}
+    ssarepr = unformat_assembler(input, regs)
+    assert regs['%i2'].kind == 'int'
+    assert regs['%i2'].index == 2
+    assert ssarepr.insns == [
+        ('int_add', regs['%i0'], regs['%i1'], regs['%i2']),
+        ('int_return', regs['%i2']),
+        ]
+
+def test_unformat_assembler_consts():
+    input = """
+        foo $123
+    """
+    ssarepr = unformat_assembler(input)
+    assert ssarepr.insns == [
+        ('foo', Constant(123, lltype.Signed)),
+        ]
+
+def test_unformat_assembler_label():
+    input = """
+        L1:
+        foo L2
+        L2:
+        bar L1
+    """
+    ssarepr = unformat_assembler(input)
+    assert ssarepr.insns == [
+        (Label('L1'),),
+        ('foo', TLabel('L2')),
+        (Label('L2'),),
+        ('bar', TLabel('L1')),
+        ]

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	Wed May  5 11:23:22 2010
@@ -98,6 +98,23 @@
         assert block.exitswitch == (opname, v1)
         assert block.exits == exits
 
+def test_symmetric():
+    ops = {'int_add': 'int_add',
+           'int_gt': 'int_lt',
+           'int_le': 'int_ge'}
+    v3 = varoftype(lltype.Signed)
+    for v1 in [varoftype(lltype.Signed), Constant(42, lltype.Signed)]:
+        for v2 in [varoftype(lltype.Signed), Constant(43, lltype.Signed)]:
+            for name1, name2 in ops.items():
+                op = SpaceOperation(name1, [v1, v2], v3)
+                op1 = Transformer(FakeCPU()).rewrite_operation(op)
+                if isinstance(v1, Constant) and isinstance(v2, Variable):
+                    assert op1.opname == name2
+                    assert op1.args == [v2, v1]
+                    assert op1.result == v3
+                else:
+                    assert op1 is op
+
 def test_residual_call():
     for RESTYPE in [lltype.Signed, rclass.OBJECTPTR,
                     lltype.Float, lltype.Void]:

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py	Wed May  5 11:23:22 2010
@@ -3,6 +3,7 @@
 from pypy.jit.codewriter.test.test_flatten import fake_regallocs
 from pypy.jit.codewriter.flatten import flatten_graph
 from pypy.jit.codewriter.format import assert_format
+from pypy.objspace.flow.model import SpaceOperation
 
 
 class TestFlatten:
@@ -11,12 +12,22 @@
         self.rtyper = support.annotate(func, values, type_system=type_system)
         return self.rtyper.annotator.translator.graphs
 
+    def add_G_prefix(self, graph):
+        """Add a 'G_' prefix to the opnames 'int_add' and 'int_mul'."""
+        def with_prefix(op):
+            if op.opname in ('int_add', 'int_mul'):
+                return SpaceOperation('G_' + op.opname, op.args, op.result)
+            return op
+        #
+        for block in graph.iterblocks():
+            if block.operations:
+                block.operations = map(with_prefix, block.operations)
+
     def encoding_test(self, func, args, expected,
                       switches_require_liveness=False):
         graphs = self.make_graphs(func, args)
-        compute_liveness(graphs[0],
-                         switches_require_liveness=switches_require_liveness,
-                         opnames_requiring_liveness=['int_add', 'int_mul'])
+        self.add_G_prefix(graphs[0])
+        compute_liveness(graphs[0], switches_require_liveness)
         ssarepr = flatten_graph(graphs[0], fake_regallocs())
         assert_format(ssarepr, expected)
 
@@ -25,7 +36,7 @@
             return n + 10
         self.encoding_test(f, [5], """
             -live-
-            int_add %i0, $10, %i1
+            G_int_add %i0, $10, %i1
             int_return %i1
         """)
 
@@ -34,15 +45,15 @@
             return (n + 10) * (n + 3) * (n + 6)
         self.encoding_test(f, [5], """
             -live- %i0
-            int_add %i0, $10, %i1
+            G_int_add %i0, $10, %i1
             -live- %i0, %i1
-            int_add %i0, $3, %i2
+            G_int_add %i0, $3, %i2
             -live- %i0
-            int_mul %i1, %i2, %i3
+            G_int_mul %i1, %i2, %i3
             -live- %i3
-            int_add %i0, $6, %i4
+            G_int_add %i0, $6, %i4
             -live-
-            int_mul %i3, %i4, %i5
+            G_int_mul %i3, %i4, %i5
             int_return %i5
         """)
 
@@ -53,17 +64,17 @@
             return y+2
         self.encoding_test(f, [5, 6], """
             -live- %i0, %i1
-            int_add %i0, $5, %i2
+            G_int_add %i0, $5, %i2
             int_is_true %i2, %i3
             goto_if_not L1, %i3
             int_copy %i0, %i4
             -live-
-            int_add %i4, $1, %i5
+            G_int_add %i4, $1, %i5
             int_return %i5
             L1:
             int_copy %i1, %i6
             -live-
-            int_add %i6, $2, %i7
+            G_int_add %i6, $2, %i7
             int_return %i7
         """)
 
@@ -74,18 +85,18 @@
             return x+2
         self.encoding_test(f, [5, 6], """
             -live- %i0, %i1
-            int_add %i0, $5, %i2
+            G_int_add %i0, $5, %i2
             int_is_true %i2, %i3
             goto_if_not L1, %i3
             int_copy %i0, %i4
             int_copy %i1, %i5
             -live-
-            int_add %i4, %i5, %i6
+            G_int_add %i4, %i5, %i6
             int_return %i6
             L1:
             int_copy %i0, %i7
             -live-
-            int_add %i7, $2, %i8
+            G_int_add %i7, $2, %i8
             int_return %i8
         """)
 
@@ -96,17 +107,17 @@
             return x+2
         self.encoding_test(f, [5, 6], """
             -live- %i0
-            int_add %i0, %i1, %i2
+            G_int_add %i0, %i1, %i2
             int_is_true %i2, %i3
             goto_if_not L1, %i3
             int_copy %i0, %i4
             -live-
-            int_add %i4, $5, %i5
+            G_int_add %i4, $5, %i5
             int_return %i5
             L1:
             int_copy %i0, %i6
             -live-
-            int_add %i6, $2, %i7
+            G_int_add %i6, $2, %i7
             int_return %i7
         """)
 

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	Wed May  5 11:23:22 2010
@@ -5,6 +5,7 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.debug import debug_start, debug_stop, debug_print
+from pypy.rlib.debug import make_sure_not_resized
 
 from pypy.jit.metainterp import history, compile, resume
 from pypy.jit.metainterp.history import Const, ConstInt, ConstPtr, ConstFloat
@@ -97,17 +98,23 @@
     prepare_list_of_boxes._annspecialcase_ = 'specialize:arg(4)'
 
     def get_list_of_active_boxes(self):
-        # XXX find a way to avoid needing the temporary 'env' as a
-        # variable-sized list
-        env = []
+        count = self.jitcode.enumerate_live_vars(
+            self.pc, MIFrame._count_boxes, None,
+            self.registers_i, self.registers_r, self.registers_f)
+        env = [None] * count
         self.jitcode.enumerate_live_vars(
             self.pc, MIFrame._store_in_env, env,
             self.registers_i, self.registers_r, self.registers_f)
-        return env[:]
+        make_sure_not_resized(env)
+        return env
+
+    @staticmethod
+    def _count_boxes(_, box, index):
+        pass    # just used to count how many boxes there are
 
     @staticmethod
-    def _store_in_env(env, box):
-        env.append(box)
+    def _store_in_env(env, box, index):
+        env[index] = box
 
     def replace_active_box_in_frame(self, oldbox, newbox):
         if isinstance(oldbox, history.BoxInt):
@@ -158,7 +165,6 @@
     for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not',
                     'cast_ptr_to_int', 'cast_float_to_int',
                     'cast_int_to_float', 'float_neg', 'float_abs',
-                    'float_is_true',
                     ]:
         exec py.code.Source('''
             @arguments("box")

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	Wed May  5 11:23:22 2010
@@ -156,7 +156,6 @@
     'FLOAT_TRUEDIV/2',
     'FLOAT_NEG/1',
     'FLOAT_ABS/1',
-    'FLOAT_IS_TRUE/1b',
     'CAST_FLOAT_TO_INT/1',
     'CAST_INT_TO_FLOAT/1',
     #

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py	Wed May  5 11:23:22 2010
@@ -118,7 +118,6 @@
         assert get_stats().aborted_count >= count
 
     def meta_interp(self, *args, **kwds):
-        py.test.skip("XXX")
         kwds['CPUClass'] = self.CPUClass
         kwds['type_system'] = self.type_system
         if "backendopt" not in kwds:
@@ -142,7 +141,6 @@
 
     def check_operations_history(self, expected=None, **isns):
         # this can be used after interp_operations
-        py.test.skip("XXX")
         self.metainterp.staticdata.stats.check_history(expected, **isns)
 
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_codewriter.py	Wed May  5 11:23:22 2010
@@ -9,109 +9,6 @@
 from pypy.translator.translator import graphof
 from pypy.rpython.lltypesystem.rbuiltin import ll_instantiate
 
-def test_find_all_graphs():
-    def f(x):
-        if x < 0:
-            return f(-x)
-        return x + 1
-    @jit.purefunction
-    def g(x):
-        return x + 2
-    @jit.dont_look_inside
-    def h(x):
-        return x + 3
-    def i(x):
-        return f(x) * g(x) * h(x)
-
-    rtyper = support.annotate(i, [7])
-    cw = CodeWriter(rtyper)
-    jitpolicy = JitPolicy()
-    res = cw.find_all_graphs(rtyper.annotator.translator.graphs[0],
-                             jitpolicy, True)
-    translator = rtyper.annotator.translator
-
-    funcs = set([graph.func for graph in res])
-    assert funcs == set([i, f])
-
-def test_find_all_graphs_without_floats():
-    def g(x):
-        return int(x * 12.5)
-    def f(x):
-        return g(x) + 1
-    rtyper = support.annotate(f, [7])
-    cw = CodeWriter(rtyper)
-    jitpolicy = JitPolicy()
-    translator = rtyper.annotator.translator
-    res = cw.find_all_graphs(translator.graphs[0], jitpolicy,
-                             supports_floats=True)
-    funcs = set([graph.func for graph in res])
-    assert funcs == set([f, g])
-
-    cw = CodeWriter(rtyper)        
-    res = cw.find_all_graphs(translator.graphs[0], jitpolicy,
-                             supports_floats=False)
-    funcs = [graph.func for graph in res]
-    assert funcs == [f]
-
-def test_find_all_graphs_loops():
-    def g(x):
-        i = 0
-        while i < x:
-            i += 1
-        return i
-    @jit.unroll_safe
-    def h(x):
-        i = 0
-        while i < x:
-            i += 1
-        return i
-
-    def f(x):
-        i = 0
-        while i < x*x:
-            i += g(x) + h(x)
-        return i
-
-    rtyper = support.annotate(f, [7])
-    cw = CodeWriter(rtyper)
-    jitpolicy = JitPolicy()
-    translator = rtyper.annotator.translator
-    res = cw.find_all_graphs(translator.graphs[0], jitpolicy,
-                             supports_floats=True)
-    funcs = set([graph.func for graph in res])
-    assert funcs == set([f, h])
-
-def test_unroll_safe_and_inline():
-    @jit.unroll_safe
-    def h(x):
-        i = 0
-        while i < x:
-            i += 1
-        return i
-    h._always_inline_ = True
-
-    def g(x):
-        return h(x)
-
-    rtyper = support.annotate(g, [7])
-    cw = CodeWriter(rtyper)
-    jitpolicy = JitPolicy()
-    translator = rtyper.annotator.translator
-    res = cw.find_all_graphs(translator.graphs[0], jitpolicy,
-                             supports_floats=True)
-    funcs = set([graph.func for graph in res])
-    assert funcs == set([g, h])
-
-def test_find_all_graphs_str_join():
-    def i(x, y):
-        return "hello".join([str(x), str(y), "bye"])
-
-    rtyper = support.annotate(i, [7, 100])
-    cw = CodeWriter(rtyper)
-    jitpolicy = JitPolicy()
-    translator = rtyper.annotator.translator
-    # does not explode
-    cw.find_all_graphs(translator.graphs[0], jitpolicy, True)
 
 class SomeLabel(object):
     def __eq__(self, other):

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py	Wed May  5 11:23:22 2010
@@ -152,9 +152,8 @@
         self.set_translator(translator)
         self.find_portal()
         self.codewriter = codewriter.CodeWriter(self.rtyper)
-        graphs = self.codewriter.find_all_graphs(self.portal_graph,
-                                                 policy,
-                                                 CPUClass.supports_floats)
+        policy.set_supports_floats(CPUClass.supports_floats)
+        graphs = self.codewriter.find_all_graphs(self.portal_graph, policy)
         policy.dump_unsafe_loops()
         self.check_access_directly_sanity(graphs)
         if backendopt:



More information about the Pypy-commit mailing list