[pypy-svn] r67859 - in pypy/branch/remove-plfbid/pypy/jit: backend backend/llgraph backend/llsupport backend/llsupport/test backend/test metainterp metainterp/test

pedronis at codespeak.net pedronis at codespeak.net
Wed Sep 23 20:24:09 CEST 2009


Author: pedronis
Date: Wed Sep 23 20:24:08 2009
New Revision: 67859

Modified:
   pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/runner.py
   pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/descr.py
   pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/llmodel.py
   pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/test/test_runner.py
   pypy/branch/remove-plfbid/pypy/jit/backend/model.py
   pypy/branch/remove-plfbid/pypy/jit/backend/test/runner_test.py
   pypy/branch/remove-plfbid/pypy/jit/backend/test/test_ll_random.py
   pypy/branch/remove-plfbid/pypy/jit/backend/test/test_random.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/graphpage.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/history.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/resoperation.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/oparser.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_oparser.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizefindnode.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/warmspot.py
Log:
(arigo, pedronis) getting somewhere in terms of a saner backend interface



Modified: pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/llimpl.py	Wed Sep 23 20:24:08 2009
@@ -353,7 +353,6 @@
 def compile_add_fail(loop, fail_index):
     loop = _from_opaque(loop)
     op = loop.operations[-1]
-    assert op.opnum == rop.FAIL
     op.fail_index = fail_index
 
 def compile_suboperations(loop):
@@ -440,6 +439,13 @@
                         ', '.join(map(str, args)),))
                 self.fail_args = args
                 return op.fail_index
+            elif op.opnum == rop.FINISH:
+                if self.verbose:
+                    log.trace('finished: %s' % (
+                        ', '.join(map(str, args)),))
+                self.fail_args = args
+                return op.fail_index
+ 
             else:
                 assert 0, "unknown final operation %d" % (op.opnum,)
 

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/llgraph/runner.py	Wed Sep 23 20:24:08 2009
@@ -85,7 +85,7 @@
         self.stats.exec_jumps = 0
         self.stats.exec_conditional_jumps = 0
         self.memo_cast = llimpl.new_memo_cast()
-        self.fail_ops = []
+        self.fail_descrs = []
         llimpl._stats = self.stats
         llimpl._llinterp = LLInterpreter(self.rtyper)
         if translate_support_code:
@@ -103,15 +103,11 @@
                 size = size.ofs
             llimpl.set_class_size(self.memo_cast, vtable, size)
 
-    def compile_loop(self, loop):
-        return self._compile_operations(loop.inputargs, loop.operations)
+    def compile_bridge(self, faildescr, inputargs, operations):
+        c = self.compile_loop(inputargs, operations)
+        llimpl.compile_redirect_fail(faildescr._compiled_fail, c)        
 
-    def compile_bridge(self, guard_op):
-        inputargs = guard_op._fail_op.args # xxx unhappy
-        c = self._compile_operations(inputargs, guard_op.suboperations)
-        llimpl.compile_redirect_fail(guard_op._compiled_fail, c)        
-
-    def _compile_operations(self, inputargs, operations):
+    def compile_loop(self, inputargs, operations):
         """In a real assembler backend, this should assemble the given
         list of operations.  Here we just generate a similar CompiledLoop
         instance.  The code here is RPython, whereas the code in llimpl
@@ -160,8 +156,6 @@
                 suboperations = op.suboperations
                 assert len(suboperations) == 1
                 assert suboperations[0].opnum == rop.FAIL
-                op._fail_op = suboperations[0] # xxx unhappy
-                op._compiled_fail = c2
                 self._compile_branch(c2, op.suboperations, var2index.copy())
             x = op.result
             if x is not None:
@@ -184,8 +178,18 @@
                 target = target.executable_token
             llimpl.compile_add_jump_target(c, target)
         elif op.opnum == rop.FAIL:
-            llimpl.compile_add_fail(c, len(self.fail_ops))
-            self.fail_ops.append(op)
+            faildescr = op.descr
+            assert isinstance(faildescr, history.AbstractFailDescr)
+            faildescr._compiled_fail = c
+            llimpl.compile_add_fail(c, len(self.fail_descrs))
+            self.fail_descrs.append(faildescr)
+        elif op.opnum == rop.FINISH:
+            llimpl.compile_add_fail(c, len(self.fail_descrs))
+            faildescr = op.descr
+            assert isinstance(faildescr, history.AbstractFailDescr)            
+            self.fail_descrs.append(faildescr)            
+        else:
+            assert False, "unknown operation"
 
     def execute_token(self, compiled_version):
         """Calls the assembler generated for the given loop.
@@ -198,7 +202,7 @@
         fail_index = llimpl.frame_execute(frame)
         # we hit a FAIL operation.
         self.latest_frame = frame
-        return self.fail_ops[fail_index]
+        return self.fail_descrs[fail_index]
 
     def set_future_value_int(self, index, intvalue):
         llimpl.set_future_value_int(index, intvalue)

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/descr.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/descr.py	Wed Sep 23 20:24:08 2009
@@ -1,7 +1,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr
-from pypy.jit.metainterp.history import TreeLoop
+from pypy.jit.metainterp.history import AbstractFailDescr
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 
 # The point of the class organization in this file is to make instances
@@ -165,7 +165,7 @@
 
 class BaseCallDescr(AbstractDescr):
     _clsname = ''
-    call_loop = None
+    executable_token = None
     arg_classes = ''     # <-- annotation hack
 
     def __init__(self, arg_classes):
@@ -185,9 +185,9 @@
     def get_result_size(self, translate_support_code):
         raise NotImplementedError
 
-    def get_loop_for_call(self, cpu):
-        if self.call_loop is not None:
-            return self.call_loop
+    def get_token_for_call(self, cpu):
+        if self.executable_token is not None:
+            return self.executable_token
         args = [BoxInt()] + self.instantiate_arg_classes()
         if self.get_result_size(cpu.translate_support_code) == 0:
             result = None
@@ -201,14 +201,13 @@
         operations = [
             ResOperation(rop.CALL, args, result, self),
             ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
-            ResOperation(rop.FAIL, result_list, None)]
-        operations[1].suboperations = [ResOperation(rop.FAIL, [], None)]
-        loop = TreeLoop('call')
-        loop.inputargs = args
-        loop.operations = operations
-        cpu.compile_loop(loop)
-        self.call_loop = loop
-        return loop
+            ResOperation(rop.FAIL, result_list, None,
+                         descr=AbstractFailDescr())]
+        operations[1].suboperations = [ResOperation(rop.FAIL, [], None,
+                                                    descr=AbstractFailDescr())]
+        executable_token = cpu.compile_loop(args, operations)
+        self.executable_token = executable_token
+        return executable_token
 
     def repr_of_descr(self):
         return '<%s>' % self._clsname

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/llmodel.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/llmodel.py	Wed Sep 23 20:24:08 2009
@@ -420,9 +420,9 @@
         if not we_are_translated():
             assert (list(calldescr.arg_classes) ==
                     [arg.type for arg in args[1:]])
-        loop = calldescr.get_loop_for_call(self)
+        executable_token = calldescr.get_token_for_call(self)
         set_future_values(self, args)
-        self.execute_operations(loop)
+        self.execute_token(executable_token)
         # Note: if an exception is set, the rest of the code does a bit of
         # nonsense but nothing wrong (the return value should be ignored)
         if calldescr.returns_a_pointer():

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/test/test_runner.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/test/test_runner.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/llsupport/test/test_runner.py	Wed Sep 23 20:24:08 2009
@@ -7,7 +7,7 @@
     pass
 
 class MyLLCPU(AbstractLLCPU):
-    def compile_loop(self, loop):
+    def compile_loop(self, inputargs, operations):
         py.test.skip("llsupport test: cannot compile operations")
 
 

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/model.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/model.py	Wed Sep 23 20:24:08 2009
@@ -8,12 +8,12 @@
         """Called once by the front-end when the program starts."""
         pass
 
-    def compile_loop(self, loop):
+    def compile_loop(self, inputargs, operations):
         """Assemble the given loop.
            Return an opaque token to be consumed by execute_token"""
         raise NotImplementedError
 
-    def compile_bridge(self, guard_op): # xxx unhappy
+    def compile_bridge(self, faildescr, inputargs, operations):
         """Assemble the bridge"""
         raise NotImplementedError    
 

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/test/runner_test.py	Wed Sep 23 20:24:08 2009
@@ -1,7 +1,8 @@
 
 import py, sys, random
-from pypy.jit.metainterp.history import (BoxInt, Box, BoxPtr,
-                                         TreeLoop, LoopToken,
+from pypy.jit.metainterp.history import (AbstractDescr, AbstractFailDescr,
+                                         BoxInt, Box, BoxPtr,
+                                         LoopToken,
                                          ConstInt, ConstPtr, BoxObj, Const,
                                          ConstObj, BoxFloat, ConstFloat)
 from pypy.jit.metainterp.resoperation import ResOperation, rop
@@ -14,12 +15,16 @@
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rpython.llinterp import LLException
 
+FailDescr = AbstractFailDescr
+
 class Runner(object):
 
     def execute_operation(self, opname, valueboxes, result_type, descr=None):
-        loop = self._get_single_operation_loop(opname, result_type,
-                                               valueboxes, descr)
-        executable_token = self.cpu.compile_loop(loop)
+        inputargs, operations = self._get_single_operation_list(opname,
+                                                                result_type,
+                                                                valueboxes,
+                                                                descr)
+        executable_token = self.cpu.compile_loop(inputargs, operations)
         j = 0
         for box in valueboxes:
             if isinstance(box, BoxInt):
@@ -34,7 +39,7 @@
             else:
                 assert isinstance(box, Const)
         res = self.cpu.execute_token(executable_token)
-        if res is loop.operations[-1]:
+        if res is operations[-1].descr:
             self.guard_failed = False
         else:
             self.guard_failed = True
@@ -49,7 +54,7 @@
         else:
             assert False
 
-    def _get_single_operation_loop(self, opnum, result_type, valueboxes,
+    def _get_single_operation_list(self, opnum, result_type, valueboxes,
                                    descr):
         if result_type == 'void':
             result = None
@@ -66,128 +71,159 @@
         else:
             results = [result]
         operations = [ResOperation(opnum, valueboxes, result),
-                      ResOperation(rop.FAIL, results, None)]
+                      ResOperation(rop.FAIL, results, None,
+                                   descr=FailDescr())]
         operations[0].descr = descr
         if operations[0].is_guard():
             operations[0].suboperations = [ResOperation(rop.FAIL,
-                                                        [ConstInt(-13)], None)]
-        loop = TreeLoop('single op')
-        loop.operations = operations
-        loop.inputargs = []
+                                                        [ConstInt(-13)], None,
+                                                        descr=FailDescr())]
+        inputargs = []
         for box in valueboxes:
             if isinstance(box, Box):
-                assert box not in loop.inputargs, "repeated box!"
-                loop.inputargs.append(box)
-        return loop
+                assert box not in inputargs, "repeated box!"
+                inputargs.append(box)
+        return inputargs, operations
 
 class BaseBackendTest(Runner):
 
     def test_compile_linear_loop(self):
-        loop = TreeLoop('single op')
         i0 = BoxInt()
         i1 = BoxInt()
-        loop.operations = [
+        faildescr = FailDescr()
+        operations = [
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
-            ResOperation(rop.FAIL, [i1], None)
+            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
             ]
-        loop.inputargs = [i0]
-        executable_token = self.cpu.compile_loop(loop)
+        inputargs = [i0]
+        executable_token = self.cpu.compile_loop(inputargs, operations)
         self.cpu.set_future_value_int(0, 2)
-        fail_op = self.cpu.execute_token(executable_token)
-        assert fail_op is loop.operations[-1] # xxx unhappy
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr
         res = self.cpu.get_latest_value_int(0)
         assert res == 3
 
     def test_compile_loop(self):
-        loop = TreeLoop('single op')
         i0 = BoxInt()
         i1 = BoxInt()
         i2 = BoxInt()
-        loop.operations = [
+        faildescr = FailDescr()        
+        operations = [
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
             ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
             ResOperation(rop.GUARD_TRUE, [i2], None),
             ResOperation(rop.JUMP, [i1], None),
             ]
-        loop.inputargs = [i0]
-        loop.operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None)
+        inputargs = [i0]
+        operations[2].suboperations = [
+            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
             ]
-        loop.operations[-1].jump_target = None
+        operations[-1].jump_target = None
         
-        executable_token = self.cpu.compile_loop(loop)
+        executable_token = self.cpu.compile_loop(inputargs, operations)
         self.cpu.set_future_value_int(0, 2)
-        fail_op = self.cpu.execute_token(executable_token)
-        assert fail_op is loop.operations[2].suboperations[-1] # xxx unhappy
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr
         res = self.cpu.get_latest_value_int(0)
         assert res == 10
 
     def test_backends_dont_keep_loops_alive(self):
         import weakref, gc
-        loop = TreeLoop('single op')
         i0 = BoxInt()
         i1 = BoxInt()
         i2 = BoxInt()
-        loop.operations = [
+        faildescr = FailDescr()                
+        operations = [
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
             ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
             ResOperation(rop.GUARD_TRUE, [i2], None),
             ResOperation(rop.JUMP, [i1], None),
             ]
-        loop.inputargs = [i0]
-        loop.operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None)
+        inputargs = [i0]
+        operations[2].suboperations = [
+            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
             ]
-        loop.operations[-1].jump_target = None
-        
-        executable_token = self.cpu.compile_loop(loop)        
-        wr = weakref.ref(loop)
-        del loop
+        operations[-1].jump_target = None
+        wr_i1 = weakref.ref(i1)
+        wr_guard = weakref.ref(operations[2])
+        wr_fail = weakref.ref(operations[2].suboperations[0])        
+        executable_token = self.cpu.compile_loop(inputargs, operations)
+        del i0, i1, i2
+        del inputargs
+        del operations
         gc.collect()
-        assert not wr()
+        assert not wr_i1() and not wr_guard() and not wr_fail()
 
     def test_compile_bridge(self):
-        loop = TreeLoop('single op')
         i0 = BoxInt()
         i1 = BoxInt()
         i2 = BoxInt()
-        loop.operations = [
+        faildescr1 = FailDescr()
+        faildescr2 = FailDescr()
+        operations = [
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
             ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
             ResOperation(rop.GUARD_TRUE, [i2], None),
             ResOperation(rop.JUMP, [i1], None),
             ]
-        loop.inputargs = [i0]
-        loop.operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None)
+        inputargs = [i0]
+        operations[2].suboperations = [
+            ResOperation(rop.FAIL, [i1], None, descr=faildescr1)
             ]
-        loop.operations[-1].jump_target = None       
-        executable_token = self.cpu.compile_loop(loop)
+        operations[-1].jump_target = None       
+        executable_token = self.cpu.compile_loop(inputargs, operations)
         loop_token = LoopToken()
         loop_token.executable_token = executable_token
 
+        i1b = BoxInt()
         i3 = BoxInt()
         bridge = [
-            ResOperation(rop.INT_LE, [i1, ConstInt(19)], i3),
+            ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
             ResOperation(rop.GUARD_TRUE, [i3], None),
-            ResOperation(rop.JUMP, [i1], None),            
+            ResOperation(rop.JUMP, [i1b], None),            
         ]
         bridge[1].suboperations = [
-            ResOperation(rop.FAIL, [i1], None)
+            ResOperation(rop.FAIL, [i1b], None, descr=faildescr2)
             ]
         bridge[-1].jump_target = loop_token
 
-        # xxx unhappy
-        guard_op = loop.operations[2]
-        guard_op.suboperations = bridge
-        self.cpu.compile_bridge(guard_op)        
+        self.cpu.compile_bridge(faildescr1, [i1b], bridge)        
 
         self.cpu.set_future_value_int(0, 2)
-        fail_op = self.cpu.execute_token(executable_token)
-        assert fail_op is bridge[1].suboperations[-1] # xxx unhappy
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr2
         res = self.cpu.get_latest_value_int(0)
         assert res == 20
-         
+
+    def test_finish(self):
+        i0 = BoxInt()
+        faildescr = AbstractDescr() # to check that is not touched
+        operations = [
+            ResOperation(rop.FINISH, [i0], None, descr=faildescr)
+            ]
+        executable_token = self.cpu.compile_loop([i0], operations)
+        self.cpu.set_future_value_int(0, 99)
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr
+        res = self.cpu.get_latest_value_int(0)
+        assert res == 99
+
+        operations = [
+            ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr)
+            ]
+        executable_token = self.cpu.compile_loop([], operations)
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr        
+        res = self.cpu.get_latest_value_int(0)
+        assert res == 42
+
+        operations = [
+            ResOperation(rop.FINISH, [], None, descr=faildescr)
+            ]
+        executable_token = self.cpu.compile_loop([], operations)
+        fail = self.cpu.execute_token(executable_token)
+        assert fail is faildescr
+        
     def test_do_call(self):
         cpu = self.cpu
         #
@@ -360,32 +396,31 @@
                 ops = [
                     ResOperation(opnum, [v1, v2], v_res),
                     ResOperation(rop.GUARD_NO_OVERFLOW, [], None),
-                    ResOperation(rop.FAIL, [v_res], None),
+                    ResOperation(rop.FAIL, [v_res], None, descr=FailDescr()),
                     ]
-                ops[1].suboperations = [ResOperation(rop.FAIL, [], None)]
+                ops[1].suboperations = [ResOperation(rop.FAIL, [], None,
+                                                     descr=FailDescr())]
             else:
                 v_exc = self.cpu.ts.BoxRef()
                 ops = [
                     ResOperation(opnum, [v1, v2], v_res),
                     ResOperation(rop.GUARD_OVERFLOW, [], None),
-                    ResOperation(rop.FAIL, [], None),
+                    ResOperation(rop.FAIL, [], None, descr=FailDescr()),
                     ]
-                ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None)]
+                ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None,
+                                                     descr=FailDescr())]
             #
-            loop = TreeLoop('name')
-            loop.operations = ops
-            loop.inputargs = [v1, v2]
-            executable_token = self.cpu.compile_loop(loop)
+            executable_token = self.cpu.compile_loop([v1, v2], ops)
             for x, y, z in testcases:
                 assert not self.cpu.get_exception()
                 assert not self.cpu.get_exc_value()
                 self.cpu.set_future_value_int(0, x)
                 self.cpu.set_future_value_int(1, y)
-                op = self.cpu.execute_token(executable_token)
+                fail = self.cpu.execute_token(executable_token)
                 if (z == boom) ^ reversed:
-                    assert op is ops[1].suboperations[0]
+                    assert fail is ops[1].suboperations[0].descr
                 else:
-                    assert op is ops[-1]
+                    assert fail is ops[-1].descr
                 if z != boom:
                     assert self.cpu.get_latest_value_int(0) == z
                 assert not self.cpu.get_exception()
@@ -1015,7 +1050,8 @@
         exc_tp = xtp
         exc_ptr = xptr
         loop = parse(ops, self.cpu, namespace=locals())
-        executable_token = self.cpu.compile_loop(loop)
+        executable_token = self.cpu.compile_loop(loop.inputargs,
+                                                 loop.operations)
         self.cpu.set_future_value_int(0, 1)
         self.cpu.execute_token(executable_token)
         assert self.cpu.get_latest_value_int(0) == 0
@@ -1038,7 +1074,8 @@
         exc_tp = ytp
         exc_ptr = yptr
         loop = parse(ops, self.cpu, namespace=locals())
-        executable_token = self.cpu.compile_loop(loop)
+        executable_token = self.cpu.compile_loop(loop.inputargs,
+                                                 loop.operations)
         self.cpu.set_future_value_int(0, 1)
         self.cpu.execute_token(executable_token)
         assert self.cpu.get_latest_value_int(0) == 1
@@ -1054,7 +1091,8 @@
         fail(0)
         '''
         loop = parse(ops, self.cpu, namespace=locals())
-        executable_token = self.cpu.compile_loop(loop)
+        executable_token = self.cpu.compile_loop(loop.inputargs,
+                                                 loop.operations)
         self.cpu.set_future_value_int(0, 1)
         self.cpu.execute_token(executable_token)
         assert self.cpu.get_latest_value_int(0) == 1

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/test/test_ll_random.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/test/test_ll_random.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/test/test_ll_random.py	Wed Sep 23 20:24:08 2009
@@ -1,6 +1,7 @@
 import py
 from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rffi, rstr
 from pypy.jit.backend.test import test_random
+from pypy.jit.backend.test.test_random import FailDescr
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.metainterp.history import ConstInt, ConstPtr, ConstAddr, BoxPtr,\
      BoxInt
@@ -449,7 +450,8 @@
         descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
         self.put(builder, args, descr)
         op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None)
-        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None,
+                                         descr=FailDescr())]
         builder.loop.operations.append(op)
 
 # 5. Non raising-call and GUARD_EXCEPTION
@@ -471,7 +473,8 @@
         exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
         op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr())
         subset = builder.subset_of_intvars(r)
-        op.suboperations = [ResOperation(rop.FAIL, subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, subset, None,
+                                         descr=FailDescr())]
         op._exc_box = None
         builder.should_fail_by = op.suboperations[0]
         builder.guard_op = op
@@ -493,7 +496,8 @@
         assert builder.cpu.get_exception()
         builder.cpu.clear_exception()
         op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr())
-        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None,
+                                         descr=FailDescr())]
         builder.loop.operations.append(op)
 
 # 4. raising call and guard_no_exception
@@ -512,7 +516,8 @@
         op = ResOperation(rop.GUARD_NO_EXCEPTION, [], BoxPtr())
         op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
         subset = builder.subset_of_intvars(r)
-        op.suboperations = [ResOperation(rop.FAIL, subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, subset, None,
+                                         descr=FailDescr())]
         builder.should_fail_by = op.suboperations[0]
         builder.guard_op = op
         builder.loop.operations.append(op)
@@ -538,7 +543,8 @@
         op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr())
         op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
         subset = builder.subset_of_intvars(r)
-        op.suboperations = [ResOperation(rop.FAIL, subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, subset, None,
+                                         descr=FailDescr())]
         builder.should_fail_by = op.suboperations[0]
         builder.guard_op = op
         builder.loop.operations.append(op)

Modified: pypy/branch/remove-plfbid/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/backend/test/test_random.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/backend/test/test_random.py	Wed Sep 23 20:24:08 2009
@@ -2,12 +2,15 @@
 from pypy.rlib.rarithmetic import intmask, LONG_BIT
 from pypy.rpython.lltypesystem import llmemory
 from pypy.jit.backend.test import conftest as demo_conftest
-from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt, LoopToken
+from pypy.jit.metainterp.history import AbstractFailDescr, TreeLoop
+from pypy.jit.metainterp.history import BoxInt, ConstInt, LoopToken
 from pypy.jit.metainterp.history import BoxPtr, ConstPtr, ConstAddr
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.metainterp.executor import execute_nonspec
 from pypy.jit.metainterp.resoperation import opname
 
+FailDescr = AbstractFailDescr
+
 class PleaseRewriteMe(Exception):
     pass
 
@@ -139,11 +142,10 @@
         print_loop_prebuilt(self.loop.operations)
         #
         print >>s, '    cpu = CPU(None, None)'
-        print >>s, "    loop = TreeLoop('test')"
         if hasattr(self.loop, 'inputargs'):
-            print >>s, '    loop.inputargs = [%s]' % (
+            print >>s, '    inputargs = [%s]' % (
                 ', '.join([names[v] for v in self.loop.inputargs]))
-        print >>s, '    loop.operations = ['
+        print >>s, '    operations = ['
         for op in self.loop.operations:
             self.process_operation(s, op, names, subops)
         print >>s, '        ]'
@@ -156,10 +158,10 @@
                 #    continue # XXX
                 #[op] = op.suboperations
                 #assert op.opnum == rop.FAIL
-                #print >>s, '    loop.operations[%d].suboperations = [' % i
+                #print >>s, '    operations[%d].suboperations = [' % i
                 #print >>s, '        ResOperation(rop.FAIL, [%s], None)]' % (
                 #    ', '.join([names[v] for v in op.args]))
-        print >>s, '    executable_token = cpu.compile_loop(loop)'
+        print >>s, '    executable_token = cpu.compile_loop(inputargs, operations)'
         if hasattr(self.loop, 'inputargs'):
             for i, v in enumerate(self.loop.inputargs):
                 print >>s, '    cpu.set_future_value_int(%d, %d)' % (i,
@@ -246,7 +248,8 @@
             builder.intvars[:] = original_intvars
         else:
             op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
-        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, fail_subset, None,
+                                         descr=FailDescr())]
         builder.loop.operations.append(op)
 
 class BinaryOvfOperation(AbstractOvfOperation, BinaryOperation):
@@ -264,7 +267,8 @@
         op, passing = self.gen_guard(builder, r)
         builder.loop.operations.append(op)
         subset = builder.subset_of_intvars(r)        
-        op.suboperations = [ResOperation(rop.FAIL, subset, None)]
+        op.suboperations = [ResOperation(rop.FAIL, subset, None,
+                                         descr=FailDescr())]
         if not passing:
             builder.should_fail_by = op.suboperations[0]
             builder.guard_op = op
@@ -405,7 +409,8 @@
         self.generate_ops(builder, r, loop, startvars)
         self.builder = builder
         self.loop = loop
-        self.executable_token = cpu.compile_loop(loop)
+        self.executable_token = cpu.compile_loop(loop.inputargs,
+                                                 loop.operations)
 
     def generate_ops(self, builder, r, loop, startvars):
         block_length = demo_conftest.option.block_length
@@ -426,7 +431,8 @@
             if v not in used_later:
                 endvars.append(v)
         r.shuffle(endvars)
-        loop.operations.append(ResOperation(rop.FAIL, endvars, None))
+        loop.operations.append(ResOperation(rop.FAIL, endvars, None,
+                                            descr=FailDescr()))
         if builder.should_fail_by:
             self.should_fail_by = builder.should_fail_by
             self.guard_op = builder.guard_op
@@ -458,9 +464,9 @@
 
         for i, v in enumerate(self.values):
             cpu.set_future_value_int(i, v)
-        op = cpu.execute_token(self.executable_token)
-        assert op is self.should_fail_by
-        for i, v in enumerate(op.args):
+        fail = cpu.execute_token(self.executable_token)
+        assert fail is self.should_fail_by.descr
+        for i, v in enumerate(self.should_fail_by.args):
             value = cpu.get_latest_value_int(i)
             assert value == self.expected[v], (
                 "Got %d, expected %d for value #%d" % (value,
@@ -485,13 +491,16 @@
             else:
                 op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box],
                                   BoxPtr())
-            op.suboperations = [ResOperation(rop.FAIL, [], None)]
+            op.suboperations = [ResOperation(rop.FAIL, [], None,
+                                             descr=FailDescr())]
             return op
 
         if self.dont_generate_more:
             return False
         r = self.r
         guard_op = self.guard_op
+        fail_args = guard_op.suboperations[-1].args
+        fail_descr = guard_op.suboperations[-1].descr
         guard_op.suboperations = []
         op = self.should_fail_by
         if not op.args:
@@ -508,17 +517,20 @@
             if len(subset) == 0:
                 return False
             args = [x.clonebox() for x in subset]
-            jump_target = RandomLoop(self.builder.cpu, self.builder.fork,
+            rl = RandomLoop(self.builder.cpu, self.builder.fork,
                                      r, args)
-            executable_token = self.cpu.compile_loop(jump_target.loop)
+            executable_token = self.cpu.compile_loop(rl.loop.inputargs,
+                                                     rl.loop.operations)
             jump_op = ResOperation(rop.JUMP, subset, None)
             jump_op.jump_target = LoopToken()
             jump_op.jump_target.executable_token = executable_token
-            self.should_fail_by = jump_target.should_fail_by
-            self.expected = jump_target.expected
+            self.should_fail_by = rl.should_fail_by
+            self.expected = rl.expected
             if self.guard_op is None:
                 guard_op.suboperations[-1] = jump_op
             else:
+                print "fix me, I'm a mess"
+                return False # XXX fix me
                 self.guard_op.suboperations[0].args.extend(subset)
                 self.builder.cpu.compile_bridge(guard_op)
                 if self.guard_op.is_guard_exception():
@@ -528,13 +540,14 @@
                 self.guard_op.suboperations[-1] = jump_op
                 self.builder.cpu.compile_bridge(self.guard_op)
                 dont_compile = True
-            self.guard_op = jump_target.guard_op
-            self.prebuilt_ptr_consts += jump_target.prebuilt_ptr_consts
+            self.guard_op = rl.guard_op
+            self.prebuilt_ptr_consts += rl.prebuilt_ptr_consts
             self.dont_generate_more = True
         if r.random() < .05:
             return False
         if not dont_compile:
-            self.builder.cpu.compile_bridge(guard_op)
+            self.builder.cpu.compile_bridge(fail_descr, fail_args,
+                                            guard_op.suboperations) # xxx insane
         return True
 
 def check_random_function(cpu, BuilderClass, r, num=None, max=None):

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py	Wed Sep 23 20:24:08 2009
@@ -6,8 +6,8 @@
 
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.metainterp.history import TreeLoop, log, Box, History, LoopToken
-from pypy.jit.metainterp.history import AbstractDescr, BoxInt, BoxPtr, BoxObj,\
-     BoxFloat, Const
+from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
+from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const
 from pypy.jit.metainterp import history
 from pypy.jit.metainterp.specnode import NotSpecNode
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
@@ -23,7 +23,7 @@
                 errmsg += ': ' + str(error)
         else:
             errmsg = None
-        if loop is None or type(loop) is TerminatingLoop:
+        if loop is None: # or type(loop) is TerminatingLoop:
             extraloops = []
         else:
             extraloops = [loop]
@@ -66,6 +66,8 @@
     loop_token = LoopToken()
     loop_token.specnodes = loop.specnodes
     loop_token.executable_token = executable_token
+    if not we_are_translated():
+        loop.token = loop_token
     old_loop_tokens.append(loop_token)
     return loop_token
 
@@ -74,7 +76,8 @@
     if not we_are_translated():
         show_loop(metainterp, loop)
         loop.check_consistency()
-    executable_token = metainterp.cpu.compile_loop(loop)
+    executable_token = metainterp.cpu.compile_loop(loop.inputargs,
+                                                   loop.operations)
     metainterp.staticdata.profiler.end_backend()
     metainterp.staticdata.stats.add_new_loop(loop)
     if not we_are_translated():
@@ -89,13 +92,13 @@
             debug_print("compiled new " + type)
     return executable_token
 
-def send_bridge_to_backend(metainterp, guard_op):    
+def send_bridge_to_backend(metainterp, faildescr, inputargs, operations):
     metainterp.staticdata.profiler.start_backend()
     if not we_are_translated():
         show_loop(metainterp)
-        #TreeLoop.check_consistency_of(xxx unhappy, guard_op.suboperations)
+        TreeLoop.check_consistency_of(inputargs, operations)
         pass
-    metainterp.cpu.compile_bridge(guard_op)        
+    metainterp.cpu.compile_bridge(faildescr, inputargs, operations)        
     metainterp.staticdata.profiler.end_backend()
     if not we_are_translated():
         metainterp.staticdata.stats.compiled()
@@ -107,55 +110,34 @@
 
 # ____________________________________________________________
 
-class DoneWithThisFrameDescrVoid(AbstractDescr):
-    def handle_fail_op(self, metainterp_sd, fail_op):
+class DoneWithThisFrameDescrVoid(AbstractFailDescr):
+    def handle_fail(self, metainterp_sd):
         assert metainterp_sd.result_type == 'void'
         raise metainterp_sd.DoneWithThisFrameVoid()
 
-class DoneWithThisFrameDescrInt(AbstractDescr):
-    def handle_fail_op(self, metainterp_sd, fail_op):
+class DoneWithThisFrameDescrInt(AbstractFailDescr):
+    def handle_fail(self, metainterp_sd):
         assert metainterp_sd.result_type == 'int'
-        resultbox = fail_op.args[0]
-        if isinstance(resultbox, BoxInt):
-            result = metainterp_sd.cpu.get_latest_value_int(0)
-        else:
-            assert isinstance(resultbox, history.Const)
-            result = resultbox.getint()
+        result = metainterp_sd.cpu.get_latest_value_int(0)
         raise metainterp_sd.DoneWithThisFrameInt(result)
 
-class DoneWithThisFrameDescrRef(AbstractDescr):
-    def handle_fail_op(self, metainterp_sd, fail_op):
+class DoneWithThisFrameDescrRef(AbstractFailDescr):
+    def handle_fail(self, metainterp_sd):
         assert metainterp_sd.result_type == 'ref'
-        resultbox = fail_op.args[0]
         cpu = metainterp_sd.cpu
-        if isinstance(resultbox, cpu.ts.BoxRef):
-            result = cpu.get_latest_value_ref(0)
-        else:
-            assert isinstance(resultbox, history.Const)
-            result = resultbox.getref_base()
+        result = cpu.get_latest_value_ref(0)
         raise metainterp_sd.DoneWithThisFrameRef(cpu, result)
 
-class DoneWithThisFrameDescrFloat(AbstractDescr):
-    def handle_fail_op(self, metainterp_sd, fail_op):
+class DoneWithThisFrameDescrFloat(AbstractFailDescr):
+    def handle_fail(self, metainterp_sd):
         assert metainterp_sd.result_type == 'float'
-        resultbox = fail_op.args[0]
-        if isinstance(resultbox, BoxFloat):
-            result = metainterp_sd.cpu.get_latest_value_float(0)
-        else:
-            assert isinstance(resultbox, history.Const)
-            result = resultbox.getfloat()
+        result = metainterp_sd.cpu.get_latest_value_float(0)
         raise metainterp_sd.DoneWithThisFrameFloat(result)
 
-class ExitFrameWithExceptionDescrRef(AbstractDescr):
-    def handle_fail_op(self, metainterp_sd, fail_op):
-        assert len(fail_op.args) == 1
-        valuebox = fail_op.args[0]
+class ExitFrameWithExceptionDescrRef(AbstractFailDescr):
+    def handle_fail(self, metainterp_sd):
         cpu = metainterp_sd.cpu
-        if isinstance(valuebox, cpu.ts.BoxRef):
-            value = cpu.get_latest_value_ref(0)
-        else:
-            assert isinstance(valuebox, history.Const)
-            value = valuebox.getref_base()
+        value = cpu.get_latest_value_ref(0)
         raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
 
 done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid()
@@ -168,6 +150,8 @@
 prebuiltNotSpecNode = NotSpecNode()
 
 class TerminatingLoopToken(LoopToken):
+    terminating = True
+    
     def __init__(self, nargs, finishdescr):
         self.specnodes = [prebuiltNotSpecNode]*nargs
         self.finishdescr = finishdescr
@@ -176,11 +160,7 @@
 loop_tokens_done_with_this_frame_int = [
     TerminatingLoopToken(1, done_with_this_frame_descr_int)
     ]
-# xxx they are the same now
-llhelper.loop_tokens_done_with_this_frame_ref = [
-    TerminatingLoopToken(1, done_with_this_frame_descr_ref)
-    ]
-oohelper.loop_tokens_done_with_this_frame_ref = [
+loop_tokens_done_with_this_frame_ref = [
     TerminatingLoopToken(1, done_with_this_frame_descr_ref)
     ]
 loop_tokens_done_with_this_frame_float = [
@@ -189,15 +169,11 @@
 loop_tokens_done_with_this_frame_void = [
     TerminatingLoopToken(0, done_with_this_frame_descr_void)
     ]
-# xxx they are the same now
-llhelper.loop_tokens_exit_frame_with_exception_ref = [
-    TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
-    ]
-oohelper.loop_tokens_exit_frame_with_exception_ref = [
+loop_tokens_exit_frame_with_exception_ref = [
     TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
     ]
 
-class ResumeDescr(AbstractDescr):
+class ResumeDescr(AbstractFailDescr):
     def __init__(self, original_greenkey):
         self.original_greenkey = original_greenkey
 
@@ -209,9 +185,10 @@
         self.guard_op = guard_op
         # this class also gets attributes stored by ResumeDataBuilder.finish()
 
-    def handle_fail_op(self, metainterp_sd, fail_op):
+    def handle_fail(self, metainterp_sd):
         from pypy.jit.metainterp.pyjitpl import MetaInterp
         metainterp = MetaInterp(metainterp_sd)
+        fail_op = self.get_guard_op().suboperations[-1] # xxx unhappy
         patch = self.patch_boxes_temporarily(metainterp_sd, fail_op)
         try:
             return metainterp.handle_guard_failure(fail_op, self)
@@ -268,8 +245,10 @@
         # to the corrsponding guard_op and compile from there
         # xxx unhappy
         guard_op = self.get_guard_op()
-        guard_op.suboperations = new_loop.operations
-        send_bridge_to_backend(metainterp, guard_op)
+        fail_args = guard_op.suboperations[-1].args
+        if not we_are_translated():
+            guard_op._debug_suboperations = new_loop.operations
+        send_bridge_to_backend(metainterp, self, fail_args, new_loop.operations)
 
 class ResumeFromInterpDescr(ResumeDescr):
     def __init__(self, original_greenkey, redkey):
@@ -332,5 +311,5 @@
         # e.g. loop_tokens_done_with_this_frame_void[0]
         # Replace the operation with the real operation we want, i.e. a FAIL.
         descr = target_loop_token.finishdescr
-        new_op = ResOperation(rop.FAIL, op.args, None, descr=descr)
+        new_op = ResOperation(rop.FINISH, op.args, None, descr=descr)
         new_loop.operations[-1] = new_op

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/graphpage.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/graphpage.py	Wed Sep 23 20:24:08 2009
@@ -4,8 +4,6 @@
 from pypy.jit.metainterp.history import Box
 from pypy.jit.metainterp.resoperation import rop
 
-SHOW_FAILS = False
-
 class SubGraph:
     def __init__(self, suboperations):
         self.suboperations = suboperations
@@ -15,24 +13,17 @@
         return None
 
 def display_loops(loops, errmsg=None, highlight_loops=()):
-    graphs = [(loop, loop in highlight_loops) for loop in loops]
+    graphs = [(loop, loop in highlight_loops) for loop in loops]    
     for graph, highlight in graphs:
         for op in graph.get_operations():
             if is_interesting_guard(op):
-                graphs.append((SubGraph(op.suboperations), highlight))
+                graphs.append((SubGraph(op._debug_suboperations),
+                               highlight))
     graphpage = ResOpGraphPage(graphs, errmsg)
     graphpage.display()
 
 def is_interesting_guard(op):
-    if not op.is_guard():
-        return False
-    if SHOW_FAILS:
-        return True
-    if len(op.suboperations) > 1:
-        return True
-    if op.suboperations[0].opnum == rop.FAIL:
-        return False
-    return True
+    return hasattr(op, '_debug_suboperations')
 
 
 class ResOpGraphPage(GraphPage):
@@ -40,6 +31,10 @@
     def compute(self, graphs, errmsg=None):
         resopgen = ResOpGen()
         for graph, highlight in graphs:
+            if hasattr(graph, 'token'):
+                resopgen.jumps_to_graphs[graph.token] = graph
+        
+        for graph, highlight in graphs:
             resopgen.add_graph(graph, highlight)
         if errmsg:
             resopgen.set_errmsg(errmsg)
@@ -57,6 +52,7 @@
         self.block_starters = {}    # {graphindex: {set-of-operation-indices}}
         self.all_operations = {}
         self.errmsg = None
+        self.jumps_to_graphs = {}
 
     def op_name(self, graphindex, opindex):
         return 'g%dop%d' % (graphindex, opindex)
@@ -159,7 +155,7 @@
             op = operations[opindex]
             lines.append(repr(op))
             if is_interesting_guard(op):
-                tgt = op.suboperations[0]
+                tgt = op._debug_suboperations[0]
                 tgt_g, tgt_i = self.all_operations[tgt]
                 self.genedge((graphindex, opstartindex),
                              (tgt_g, tgt_i),
@@ -171,12 +167,19 @@
                 self.genedge((graphindex, opstartindex),
                              (graphindex, opindex))
                 break
-        tgt = getattr(op, 'jump_target', None)
-        if tgt is not None and tgt in self.graphs:
-            tgt_g = self.graphs.index(tgt)
-            self.genedge((graphindex, opstartindex),
-                         (tgt_g, 0),
-                         weight="0")
+        if op.opnum == rop.JUMP:
+            tgt = op.jump_target
+            tgt_g = -1
+            if tgt is None:
+                tgt_g = graphindex
+            else:
+                tgt = self.jumps_to_graphs.get(tgt)
+                if tgt is not None:
+                    tgt_g = self.graphs.index(tgt)
+            if tgt_g != -1:
+                self.genedge((graphindex, opstartindex),
+                             (tgt_g, 0),
+                             weight="0")
         lines.append("")
         label = "\\l".join(lines)
         kwds = {}

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/history.py	Wed Sep 23 20:24:08 2009
@@ -126,6 +126,9 @@
     def repr_of_descr(self):
         return '%r' % (self,)
 
+class AbstractFailDescr(AbstractDescr):
+    pass
+
 class AbstractMethDescr(AbstractDescr):
     # the base class of the result of cpu.methdescrof()
     jitcodes = None
@@ -664,6 +667,7 @@
 
 class LoopToken(object):
     """loop token"""
+    terminating = False # see TerminatingLoopToken in compile.py
     # specnodes
     # executable_token
 
@@ -726,8 +730,11 @@
                     assert box in seen
             assert (op.suboperations is not None) == op.is_guard()
             if op.is_guard():
-                TreeLoop.check_consistency_of_branch(op.suboperations,
-                                                     seen.copy())
+                if hasattr(op, '_debug_suboperations'):
+                    ops = op._debug_suboperations
+                else:
+                    ops = op.suboperations
+                TreeLoop.check_consistency_of_branch(ops, seen.copy())
             box = op.result
             if box is not None:
                 assert isinstance(box, Box)
@@ -759,12 +766,19 @@
         return '<%s>' % (self.name,)
 
 def _list_all_operations(result, operations, omit_fails=True):
-    if omit_fails and operations[-1].opnum == rop.FAIL:
+    if omit_fails and operations[-1].opnum in (rop.FAIL, rop.FINISH):
+        # xxx obscure
         return
     result.extend(operations)
     for op in operations:
         if op.is_guard():
-            _list_all_operations(result, op.suboperations, omit_fails)
+            if hasattr(op, '_debug_suboperations'):
+                ops = op._debug_suboperations
+            else:
+                if omit_fails:
+                    continue
+                ops = op.suboperations
+            _list_all_operations(result, ops, omit_fails)
 
 # ____________________________________________________________
 
@@ -884,7 +898,7 @@
 
     def view(self, errmsg=None, extraloops=[]):
         from pypy.jit.metainterp.graphpage import display_loops
-        loops = self.get_all_loops()
+        loops = self.get_all_loops()[:]
         for loop in extraloops:
             if loop in loops:
                 loops.remove(loop)

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py	Wed Sep 23 20:24:08 2009
@@ -1505,7 +1505,7 @@
             loop_tokens = compile.loop_tokens_done_with_this_frame_int
         elif sd.result_type == 'ref':
             exits = [exitbox]
-            loop_tokens = sd.cpu.ts.loop_tokens_done_with_this_frame_ref
+            loop_tokens = compile.loop_tokens_done_with_this_frame_ref
         elif sd.result_type == 'float':
             exits = [exitbox]
             loop_tokens = compile.loop_tokens_done_with_this_frame_float
@@ -1520,7 +1520,7 @@
         self.gen_store_back_in_virtualizable()
         # temporarily put a JUMP to a pseudo-loop
         self.history.record(rop.JUMP, [valuebox], None)
-        loop_tokens = self.cpu.ts.loop_tokens_exit_frame_with_exception_ref
+        loop_tokens = compile.loop_tokens_exit_frame_with_exception_ref
         target_loop_token = compile.compile_new_bridge(self, loop_tokens,
                                                        self.resumekey)
         assert target_loop_token is loop_tokens[0]

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/resoperation.py	Wed Sep 23 20:24:08 2009
@@ -106,6 +106,7 @@
     '_FINAL_FIRST',
     'JUMP',
     'FAIL',
+    'FINISH',
     '_FINAL_LAST',
 
     '_GUARD_FIRST',

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/oparser.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/oparser.py	Wed Sep 23 20:24:08 2009
@@ -4,7 +4,7 @@
 """
 
 from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt,\
-     ConstAddr, ConstObj, ConstPtr, Box
+     ConstAddr, ConstObj, ConstPtr, Box, AbstractFailDescr
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.typesystem import llhelper
 from pypy.rpython.lltypesystem import lltype, llmemory
@@ -21,6 +21,9 @@
 class Boxes(object):
     pass
 
+FailDescr = AbstractFailDescr
+
+
 class ExtendedTreeLoop(TreeLoop):
 
     def getboxes(self):
@@ -51,7 +54,7 @@
             getattr(boxes, name).value = value
 
 class OpParser(object):
-    def __init__(self, descr, cpu, namespace, type_system, boxkinds, jump_targets):
+    def __init__(self, descr, cpu, namespace, type_system, boxkinds, jump_targets, invent_fail_descrs=True):
         self.descr = descr
         self.vars = {}
         self.cpu = cpu
@@ -60,6 +63,7 @@
         self.boxkinds = boxkinds or {}
         self.jumps = []
         self.jump_targets = jump_targets
+        self.invent_fail_descrs = invent_fail_descrs
 
     def box_for_var(self, elem):
         try:
@@ -144,30 +148,32 @@
         endnum = line.rfind(')')
         if endnum == -1:
             raise ParseError("invalid line: %s" % line)
-        argspec = line[num + 1:endnum]
-        if not argspec.strip():
-            return opnum, [], None
-        if opname == 'debug_merge_point':
-            allargs = [argspec]
-        else:
-            allargs = argspec.split(",")
         args = []
         descr = None
-        poss_descr = allargs[-1].strip()
-        if poss_descr.startswith('descr='):
-            if poss_descr.startswith('descr=<'):
-                descr = None
+        argspec = line[num + 1:endnum]
+        if argspec.strip():
+            if opname == 'debug_merge_point':
+                allargs = [argspec]
             else:
-                descr = self.consts[poss_descr[len('descr='):]]
-            allargs = allargs[:-1]        
-        for arg in allargs:
-            arg = arg.strip()
-            try:
-                args.append(self.getvar(arg))
-            except KeyError:
-                raise ParseError("Unknown var: %s" % arg)
-        if hasattr(descr, '_oparser_uses_descr'):
-            descr._oparser_uses_descr(self, args)
+                allargs = argspec.split(",")
+
+            poss_descr = allargs[-1].strip()
+            if poss_descr.startswith('descr='):
+                if poss_descr.startswith('descr=<'):
+                    descr = None
+                else:
+                    descr = self.consts[poss_descr[len('descr='):]]
+                allargs = allargs[:-1]        
+            for arg in allargs:
+                arg = arg.strip()
+                try:
+                    args.append(self.getvar(arg))
+                except KeyError:
+                    raise ParseError("Unknown var: %s" % arg)
+            if hasattr(descr, '_oparser_uses_descr'):
+                descr._oparser_uses_descr(self, args)
+        if opnum == rop.FAIL and descr is None and self.invent_fail_descrs:
+            descr = FailDescr()
         return opnum, args, descr
 
     def parse_result_op(self, line):
@@ -260,10 +266,14 @@
         return base_indent, inpargs
 
 def parse(descr, cpu=None, namespace=None, type_system='lltype',
-          boxkinds=None, jump_targets=None):
+          boxkinds=None, jump_targets=None, invent_fail_descrs=True):
     if namespace is None:
         namespace = _default_namespace[type_system]
-    return OpParser(descr, cpu, namespace, type_system, boxkinds, jump_targets).parse()
+    return OpParser(descr, cpu, namespace, type_system, boxkinds, jump_targets, invent_fail_descrs).parse()
+
+def pure_parse(*args, **kwds):
+    kwds['invent_fail_descrs'] = False
+    return parse(*args, **kwds)
 
 def _box_counter_more_than(s):
     if s.isdigit():

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_oparser.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_oparser.py	Wed Sep 23 20:24:08 2009
@@ -18,6 +18,7 @@
     assert [op.opnum for op in loop.operations] == [rop.INT_ADD, rop.INT_SUB,
                                                     rop.FAIL]
     assert len(loop.inputargs) == 2
+    assert loop.operations[-1].descr
 
 def test_const_ptr_subops():
     x = """
@@ -30,6 +31,7 @@
     loop = parse(x, None, locals())
     assert len(loop.operations) == 1
     assert len(loop.operations[0].suboperations) == 1
+    assert loop.operations[0].suboperations[-1].descr
 
 def test_descr():
     class Xyz(AbstractDescr):

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizefindnode.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizefindnode.py	Wed Sep 23 20:24:08 2009
@@ -16,8 +16,7 @@
 from pypy.jit.metainterp.specnode import VirtualArraySpecNode
 from pypy.jit.metainterp.specnode import VirtualStructSpecNode
 from pypy.jit.metainterp.specnode import ConstantSpecNode
-from pypy.jit.metainterp.test.oparser import parse
-
+from pypy.jit.metainterp.test.oparser import pure_parse as parse
 
 def test_sort_descrs():
     class PseudoDescr(AbstractDescr):

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_optimizeopt.py	Wed Sep 23 20:24:08 2009
@@ -11,7 +11,8 @@
 from pypy.jit.metainterp.history import AbstractDescr, ConstInt
 from pypy.jit.metainterp import resume, executor, compile
 from pypy.jit.metainterp.resoperation import rop, opname
-from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.test.oparser import pure_parse as parse
+    
 
 # ____________________________________________________________
 

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/warmspot.py	Wed Sep 23 20:24:08 2009
@@ -848,11 +848,10 @@
             # ---------- execute assembler ----------
             while True:     # until interrupted by an exception
                 metainterp_sd.profiler.start_running()
-                # xxx unhappy
-                fail_op = metainterp_sd.cpu.execute_token(executable_token)
+                fail_descr = metainterp_sd.cpu.execute_token(executable_token)
                 metainterp_sd.profiler.end_running()
-                executable_token = fail_op.descr.handle_fail_op(metainterp_sd,
-                                                                fail_op)
+                executable_token = fail_descr.handle_fail(metainterp_sd)
+
         maybe_compile_and_run._dont_inline_ = True
 
         def handle_hash_collision(self, firstcell, argshash, *args):



More information about the Pypy-commit mailing list