[pypy-svn] r67977 - in pypy/branch/remove-fail/pypy/jit: backend/llgraph backend/test metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Tue Sep 29 14:37:35 CEST 2009


Author: arigo
Date: Tue Sep 29 14:37:34 2009
New Revision: 67977

Modified:
   pypy/branch/remove-fail/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/remove-fail/pypy/jit/backend/llgraph/runner.py
   pypy/branch/remove-fail/pypy/jit/backend/test/runner_test.py
   pypy/branch/remove-fail/pypy/jit/metainterp/resoperation.py
   pypy/branch/remove-fail/pypy/jit/metainterp/test/oparser.py
Log:
Start to remove the FAIL operation.


Modified: pypy/branch/remove-fail/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/remove-fail/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/remove-fail/pypy/jit/backend/llgraph/llimpl.py	Tue Sep 29 14:37:34 2009
@@ -168,16 +168,16 @@
     def as_text(self, lines, indent):
         for op in self.operations:
             lines.append('\t'*indent + repr(op))
-            if op.is_guard():
-                op.subloop.as_text(lines, indent+1)
 
 class Operation(object):
+    result = None
+    descr = None
+    jump_target = None
+    fail_args = None
+
     def __init__(self, opnum):
         self.opnum = opnum
         self.args = []
-        self.result = None
-        self.descr = None
-        self.livevars = []   # for guards only
 
     def __repr__(self):
         if self.result is not None:
@@ -352,25 +352,24 @@
 
 def compile_add_fail(loop, fail_index):
     loop = _from_opaque(loop)
-    op = loop.operations[-1]
+    index = len(loop.operations)-1
+    op = loop.operations[index]
     op.fail_index = fail_index
+    return index
 
-def compile_suboperations(loop):
+def compile_add_fail_arg(loop, intvar):
     loop = _from_opaque(loop)
     op = loop.operations[-1]
-    assert op.is_guard()
-    op.subloop = CompiledLoop()
-    return _to_opaque(op.subloop)
+    if op.fail_args is None:
+        op.fail_args = []
+    op.fail_args.append(_variables[intvar])
 
-def compile_redirect_fail(old_loop, new_loop):
+def compile_redirect_fail(old_loop, old_index, new_loop):
     old_loop = _from_opaque(old_loop)
     new_loop = _from_opaque(new_loop)
-    assert len(old_loop.operations) == 1
-    assert old_loop.operations[-1].opnum == rop.FAIL
-    op = Operation(rop.JUMP)
-    op.args = old_loop.operations[-1].args
-    op.jump_target = new_loop
-    old_loop.operations[0] = op
+    guard_op = old_loop.operations[old_index]
+    assert guard_op.is_guard()
+    guard_op.jump_target = new_loop
 
 # ------------------------------
 
@@ -406,9 +405,24 @@
                 except GuardFailed:
                     assert op.is_guard()
                     _stats.exec_conditional_jumps += 1
-                    operations = op.subloop.operations
-                    opindex = 0
-                    continue
+                    if op.fail_args:
+                        args = [self.getenv(v) for v in op.fail_args]
+                    else:
+                        args = []
+                    if op.jump_target is not None:
+                        # a patched guard, pointing to further code
+                        assert len(op.jump_target.inputargs) == len(args)
+                        self.env = dict(zip(op.jump_target.inputargs, args))
+                        operations = op.jump_target.operations
+                        opindex = 0
+                        continue
+                    else:
+                        # a non-patched guard
+                        if self.verbose:
+                            log.trace('failed: %s' % (
+                                ', '.join(map(str, args)),))
+                        self.fail_args = args
+                        return op.fail_index
                 #verbose = self.verbose
                 assert (result is None) == (op.result is None)
                 if op.result is not None:
@@ -433,12 +447,6 @@
                 operations = op.jump_target.operations
                 opindex = 0
                 _stats.exec_jumps += 1
-            elif op.opnum == rop.FAIL:
-                if self.verbose:
-                    log.trace('failed: %s' % (
-                        ', '.join(map(str, args)),))
-                self.fail_args = args
-                return op.fail_index
             elif op.opnum == rop.FINISH:
                 if self.verbose:
                     log.trace('finished: %s' % (
@@ -1359,8 +1367,8 @@
 setannotation(compile_add_ref_result, annmodel.SomeInteger())
 setannotation(compile_add_float_result, annmodel.SomeInteger())
 setannotation(compile_add_jump_target, annmodel.s_None)
-setannotation(compile_add_fail, annmodel.s_None)
-setannotation(compile_suboperations, s_CompiledLoop)
+setannotation(compile_add_fail, annmodel.SomeInteger())
+setannotation(compile_add_fail_arg, annmodel.s_None)
 setannotation(compile_redirect_fail, annmodel.s_None)
 
 setannotation(new_frame, s_Frame)

Modified: pypy/branch/remove-fail/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/remove-fail/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/remove-fail/pypy/jit/backend/llgraph/runner.py	Tue Sep 29 14:37:34 2009
@@ -105,7 +105,8 @@
 
     def compile_bridge(self, faildescr, inputargs, operations):
         c = self.compile_loop(inputargs, operations)
-        llimpl.compile_redirect_fail(faildescr._compiled_fail, c)        
+        old, oldindex = faildescr._compiled_fail
+        llimpl.compile_redirect_fail(old, oldindex, c)
 
     def compile_loop(self, inputargs, operations):
         """In a real assembler backend, this should assemble the given
@@ -125,10 +126,10 @@
                 var2index[box] = llimpl.compile_start_float_var(c)
             else:
                 raise Exception("box is: %r" % (box,))
-        self._compile_branch(c, operations, var2index)
+        self._compile_operations(c, operations, var2index)
         return c
 
-    def _compile_branch(self, c, operations, var2index):
+    def _compile_operations(self, c, operations, var2index):
         for op in operations:
             llimpl.compile_add(c, op.opnum)
             descr = op.descr
@@ -152,11 +153,14 @@
                     raise Exception("%s args contain: %r" % (op.getopname(),
                                                              x))
             if op.is_guard():
-                c2 = llimpl.compile_suboperations(c)
-                suboperations = op.suboperations
-                assert len(suboperations) == 1
-                assert suboperations[0].opnum == rop.FAIL
-                self._compile_branch(c2, op.suboperations, var2index.copy())
+                faildescr = op.descr
+                assert isinstance(faildescr, history.AbstractFailDescr)
+                index = llimpl.compile_add_fail(c, len(self.fail_descrs))
+                faildescr._compiled_fail = c, index
+                self.fail_descrs.append(faildescr)
+                if op.fail_args:
+                    for box in op.fail_args:
+                        llimpl.compile_add_fail_arg(c, var2index[box])
             x = op.result
             if x is not None:
                 if isinstance(x, history.BoxInt):
@@ -177,12 +181,6 @@
             else:
                 target = target.executable_token
             llimpl.compile_add_jump_target(c, target)
-        elif op.opnum == rop.FAIL:
-            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

Modified: pypy/branch/remove-fail/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/remove-fail/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/remove-fail/pypy/jit/backend/test/runner_test.py	Tue Sep 29 14:37:34 2009
@@ -71,13 +71,11 @@
         else:
             results = [result]
         operations = [ResOperation(opnum, valueboxes, result),
-                      ResOperation(rop.FAIL, results, None,
+                      ResOperation(rop.FINISH, results, None,
                                    descr=BasicFailDescr())]
+        if operations[0].is_guard() and not descr:
+            descr = BasicFailDescr()
         operations[0].descr = descr
-        if operations[0].is_guard():
-            operations[0].suboperations = [ResOperation(rop.FAIL,
-                                                        [ConstInt(-13)], None,
-                                                        descr=BasicFailDescr())]
         inputargs = []
         for box in valueboxes:
             if isinstance(box, Box):
@@ -93,7 +91,7 @@
         faildescr = BasicFailDescr()
         operations = [
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
-            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
+            ResOperation(rop.FINISH, [i1], None, descr=faildescr)
             ]
         inputargs = [i0]
         executable_token = self.cpu.compile_loop(inputargs, operations)
@@ -107,17 +105,15 @@
         i0 = BoxInt()
         i1 = BoxInt()
         i2 = BoxInt()
-        faildescr = BasicFailDescr()        
+        faildescr = BasicFailDescr()
         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.GUARD_TRUE, [i2], None, descr=faildescr),
             ResOperation(rop.JUMP, [i1], None),
             ]
         inputargs = [i0]
-        operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
-            ]
+        operations[2].fail_args = [i1]
         operations[-1].jump_target = None
         
         executable_token = self.cpu.compile_loop(inputargs, operations)
@@ -137,23 +133,20 @@
         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.GUARD_TRUE, [i2], None, descr=faildescr),
             ResOperation(rop.JUMP, [i1], None),
             ]
         inputargs = [i0]
-        operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None, descr=faildescr)
-            ]
+        operations[2].fail_args = [i1]
         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_i1() and not wr_guard() and not wr_fail()
+        assert not wr_i1() and not wr_guard()
 
     def test_compile_bridge(self):
         i0 = BoxInt()
@@ -164,13 +157,11 @@
         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.GUARD_TRUE, [i2], None, descr=faildescr1),
             ResOperation(rop.JUMP, [i1], None),
             ]
         inputargs = [i0]
-        operations[2].suboperations = [
-            ResOperation(rop.FAIL, [i1], None, descr=faildescr1)
-            ]
+        operations[2].fail_args = [i1]
         operations[-1].jump_target = None       
         executable_token = self.cpu.compile_loop(inputargs, operations)
         loop_token = LoopToken()
@@ -180,12 +171,10 @@
         i3 = BoxInt()
         bridge = [
             ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
-            ResOperation(rop.GUARD_TRUE, [i3], None),
+            ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
             ResOperation(rop.JUMP, [i1b], None),            
         ]
-        bridge[1].suboperations = [
-            ResOperation(rop.FAIL, [i1b], None, descr=faildescr2)
-            ]
+        bridge[1].fail_args = [i1b]
         bridge[-1].jump_target = loop_token
 
         self.cpu.compile_bridge(faildescr1, [i1b], bridge)        
@@ -399,20 +388,20 @@
             if not reversed:
                 ops = [
                     ResOperation(opnum, [v1, v2], v_res),
-                    ResOperation(rop.GUARD_NO_OVERFLOW, [], None),
-                    ResOperation(rop.FAIL, [v_res], None, descr=BasicFailDescr()),
+                    ResOperation(rop.GUARD_NO_OVERFLOW, [], None,
+                                 descr=BasicFailDescr()),
+                    ResOperation(rop.FINISH, [v_res], None,
+                                 descr=BasicFailDescr()),
                     ]
-                ops[1].suboperations = [ResOperation(rop.FAIL, [], None,
-                                                     descr=BasicFailDescr())]
             else:
                 v_exc = self.cpu.ts.BoxRef()
                 ops = [
                     ResOperation(opnum, [v1, v2], v_res),
-                    ResOperation(rop.GUARD_OVERFLOW, [], None),
-                    ResOperation(rop.FAIL, [], None, descr=BasicFailDescr()),
+                    ResOperation(rop.GUARD_OVERFLOW, [], None,
+                                 descr=BasicFailDescr()),
+                    ResOperation(rop.FINISH, [], None, descr=BasicFailDescr()),
                     ]
-                ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None,
-                                                     descr=BasicFailDescr())]
+                ops[1].fail_args = [v_res]
             #
             executable_token = self.cpu.compile_loop([v1, v2], ops)
             for x, y, z in testcases:
@@ -422,7 +411,7 @@
                 self.cpu.set_future_value_int(1, y)
                 fail = self.cpu.execute_token(executable_token)
                 if (z == boom) ^ reversed:
-                    assert fail is ops[1].suboperations[0].descr
+                    assert fail is ops[1].descr
                 else:
                     assert fail is ops[-1].descr
                 if z != boom:
@@ -491,7 +480,6 @@
         for (opname, args) in [(rop.GUARD_TRUE, [BoxInt(1)]),
                                (rop.GUARD_FALSE, [BoxInt(0)]),
                                (rop.GUARD_VALUE, [BoxInt(42), BoxInt(42)]),
-                               #(rop.GUARD_VALUE_INVERSE, [BoxInt(42), BoxInt(41)]),
                                ]:
             assert self.execute_operation(opname, args, 'void') == None
             assert not self.guard_failed
@@ -1034,10 +1022,10 @@
 
         ops = '''
         [i0]
+        i1 = same_as(1)
         call(ConstClass(fptr), i0, descr=calldescr)
-        p0 = guard_exception(ConstClass(xtp))
-            fail(1)
-        fail(0, p0)
+        p0 = guard_exception(ConstClass(xtp)) [i1]
+        finish(0, p0)
         '''
         FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
         fptr = llhelper(FPTR, func)
@@ -1089,10 +1077,10 @@
         exc_ptr = xptr
         ops = '''
         [i0]
+        i1 = same_as(1)
         call(ConstClass(fptr), i0, descr=calldescr)
-        guard_no_exception()
-            fail(1)
-        fail(0)
+        guard_no_exception() [i1]
+        finish(0)
         '''
         loop = parse(ops, self.cpu, namespace=locals())
         executable_token = self.cpu.compile_loop(loop.inputargs,

Modified: pypy/branch/remove-fail/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/remove-fail/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/remove-fail/pypy/jit/metainterp/resoperation.py	Tue Sep 29 14:37:34 2009
@@ -8,8 +8,9 @@
     jump_target = None
 
     # for 'guard_*'
-    suboperations = None
-    optimized = None
+    suboperations = property(lambda x: crash, lambda x, y: crash)  # XXX temp
+    optimized = property(lambda x: crash, lambda x, y: crash)  # XXX temp
+    fail_args = None
 
     # for x86 backend and guards
     inputargs = None
@@ -105,7 +106,6 @@
 _oplist = [
     '_FINAL_FIRST',
     'JUMP',
-    'FAIL',
     'FINISH',
     '_FINAL_LAST',
 

Modified: pypy/branch/remove-fail/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/remove-fail/pypy/jit/metainterp/test/oparser.py	(original)
+++ pypy/branch/remove-fail/pypy/jit/metainterp/test/oparser.py	Tue Sep 29 14:37:34 2009
@@ -26,9 +26,6 @@
                 yield op.result
                 for box in op.args:
                     yield box
-                if op.suboperations:
-                    for box in opboxes(op.suboperations):
-                        yield box
         def allboxes():
             for box in self.inputargs:
                 yield box
@@ -167,25 +164,44 @@
                     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 = BasicFailDescr()
-        return opnum, args, descr
+        if rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST:
+            if descr is None and self.invent_fail_descrs:
+                descr = BasicFailDescr()
+            i = line.find('[', endnum) + 1
+            j = line.find(']', i)
+            if i <= 0 or j <= 0:
+                raise ParseError("missing fail_args for guard operation")
+            fail_args = []
+            for arg in line[i:j].split(','):
+                arg = arg.strip()
+                try:
+                    fail_args.append(self.vars[arg])
+                except KeyError:
+                    raise ParseError("Unknown var in fail_args: %s" % arg)
+        else:
+            fail_args = None
+            if opnum == rop.FINISH:
+                if descr is None and self.invent_fail_descrs:
+                    descr = BasicFailDescr()
+        return opnum, args, descr, fail_args
 
     def parse_result_op(self, line):
         res, op = line.split("=", 1)
         res = res.strip()
         op = op.strip()
-        opnum, args, descr = self.parse_op(op)
+        opnum, args, descr, fail_args = self.parse_op(op)
         if res in self.vars:
             raise ParseError("Double assign to var %s in line: %s" % (res, line))
         rvar = self.box_for_var(res)
         self.vars[res] = rvar
         res = ResOperation(opnum, args, rvar, descr)
+        res.fail_args = fail_args
         return res
 
     def parse_op_no_result(self, line):
-        opnum, args, descr = self.parse_op(line)
+        opnum, args, descr, fail_args = self.parse_op(line)
         res = ResOperation(opnum, args, None, descr)
+        res.fail_args = fail_args
         if opnum == rop.JUMP:
             self.jumps.append(res)
         return res
@@ -241,10 +257,7 @@
                 # dedent
                 return num, ops
             elif line.startswith(" "*(indent + 1)):
-                # suboperations
-                new_indent = len(line) - len(line.lstrip())
-                num, suboperations = self.parse_ops(new_indent, lines, num)
-                ops[-1].suboperations = suboperations
+                raise ParseError("indentation not valid any more")
             else:
                 ops.append(self.parse_next_op(lines[num].strip()))
                 num += 1



More information about the Pypy-commit mailing list