[pypy-svn] r63250 - in pypy/branch/pyjitpl5-simplify/pypy/jit: backend/llgraph metainterp

arigo at codespeak.net arigo at codespeak.net
Mon Mar 23 19:35:31 CET 2009


Author: arigo
Date: Mon Mar 23 19:35:29 2009
New Revision: 63250

Modified:
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
Log:
Bridges start to work too.


Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py	Mon Mar 23 19:35:29 2009
@@ -6,7 +6,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rclass
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.jit.metainterp import history
-from pypy.jit.metainterp.resoperation import ResOperation, rop, GuardFailure
+from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.backend.llgraph import llimpl, symbolic
 
 
@@ -126,8 +126,7 @@
 
     def execute_operations(self, loop, valueboxes):
         """Calls the assembler generated for the given loop.
-        Typically returns an instance of 'resoperation.GuardFailure';
-        may also raise an exception if the assembler code raises.
+        Returns the ResOperation that failed, of type rop.FAIL.
         """
         frame = llimpl.new_frame(self.memo_cast)
         # setup the frame
@@ -149,19 +148,17 @@
         # (in a real backend, this should be done by the FAIL operation
         # itself, not here)
         op = self.fail_ops[fail_index]
-        currentboxes = []
         for i in range(len(op.args)):
             box = op.args[i]
             if isinstance(box, history.BoxInt):
                 value = llimpl.frame_int_getvalue(frame, i)
-                box = history.BoxInt(value)
+                box.changevalue_int(value)
             elif isinstance(box, history.BoxPtr):
                 value = llimpl.frame_ptr_getvalue(frame, i)
-                box = history.BoxPtr(value)
+                box.changevalue_ptr(value)
             else:
                 raise Exception("bad box in 'fail': %r" % (box,))
-            currentboxes.append(box)
-        return GuardFailure(op.key, currentboxes)
+        return op
 
     def get_exception(self):
         return self.cast_adr_to_int(llimpl.get_exception())

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py	Mon Mar 23 19:35:29 2009
@@ -24,21 +24,20 @@
     else:
         return _compile_new_loop_1(metainterp, loop, old_loops, endliveboxes)
 
-def compile_new_bridge(metainterp, old_loops, endliveboxes):
+def compile_new_bridge(metainterp, old_loops, endliveboxes, resumekey):
     """Try to compile a new bridge leading from the beginning of the history
     to some existing place.
     """
-    bridge = create_empty_bridge(metainterp)
     if we_are_translated():
         try:
-            bridge = compile_fresh_bridge(metainterp, bridge, old_loops,
-                                          endliveboxes)
-            return bridge
+            target_loop = compile_fresh_bridge(metainterp, old_loops,
+                                               endliveboxes, resumekey)
+            return target_loop
         except optimize.CancelInefficientLoop:
             return None
     else:
-        return _compile_new_bridge_1(metainterp, bridge, old_loops,
-                                     endliveboxes)
+        return _compile_new_bridge_1(metainterp, old_loops,
+                                     endliveboxes, resumekey)
 
 class BridgeInProgress(Exception):
     pass
@@ -64,29 +63,26 @@
     loop.check_consistency()
     return loop
 
-def _compile_new_bridge_1(metainterp, bridge, old_loops, endliveboxes):
-    orgbridge = bridge
+def _compile_new_bridge_1(metainterp, old_loops, endliveboxes, resumekey):
     try:
         try:
-            bridge = compile_fresh_bridge(metainterp, bridge, old_loops,
-                                          endliveboxes)
+            target_loop = compile_fresh_bridge(metainterp, old_loops,
+                                               endliveboxes, resumekey)
         except Exception, exc:
-            show_loop(metainterp, bridge, error=exc)
+            show_loop(metainterp, error=exc)
             raise
         else:
-            if bridge == orgbridge:
-                show_loop(metainterp, bridge)
-            elif bridge is not None:
-                log.info("reusing bridge at %r" % (bridge,))
-            else:
+            if target_loop is None:
                 log.info("compile_fresh_bridge() returned None")
+            else:
+                show_loop(metainterp, target_loop)
     except optimize.CancelInefficientLoop:
         return None
-    if bridge is not None:
-        bridge.check_consistency()
-    return bridge
+    if target_loop is not None:
+        target_loop.check_consistency()
+    return target_loop
 
-def show_loop(metainterp, loop, error=None):
+def show_loop(metainterp, loop=None, error=None):
     # debugging
     if option.view:
         if error:
@@ -95,7 +91,10 @@
                 errmsg += ': ' + str(error)
         else:
             errmsg = None
-        loop.show(errmsg=errmsg)
+        if loop is None:
+            metainterp.stats.view(errmsg=errmsg)
+        else:
+            loop.show(errmsg=errmsg)
 
 def create_empty_loop(metainterp):
     if we_are_translated():
@@ -107,6 +106,10 @@
 # ____________________________________________________________
 
 def compile_fresh_loop(metainterp, loop, old_loops, endliveboxes):
+    # ---<temporary>---
+    if old_loops:
+        return old_loops[0]
+    # ---</temporary>---
     history = metainterp.history
     loop.inputargs = history.inputargs
     loop.operations = history.operations
@@ -115,7 +118,9 @@
     #                                  metainterp.cpu)
     #if old_loop is not None:
     #    return old_loop
+    mark_keys_in_loop(loop, loop.operations)
     send_loop_to_backend(metainterp, loop)
+    metainterp.stats.loops.append(loop)
     old_loops.append(loop)
     return loop
 
@@ -124,30 +129,39 @@
     op.jump_target = loop
     loop.operations.append(op)
 
+def mark_keys_in_loop(loop, operations):
+    op = None
+    for op in operations:
+        if op.is_guard():
+            mark_keys_in_loop(loop, op.suboperations)
+    if op.opnum == rop.FAIL:
+        op.key.loop = loop
+
 def send_loop_to_backend(metainterp, loop):
     metainterp.cpu.compile_operations(loop)
-    metainterp.stats.loops.append(loop)
 
 # ____________________________________________________________
 
 def matching_merge_point(metainterp, targetmp, endliveboxes):
     return True
 
-def compile_fresh_bridge(metainterp, bridge, old_loops, endliveboxes):
+def compile_fresh_bridge(metainterp, old_loops, endliveboxes, resumekey):
     history = metainterp.history
-    catch_op = history.operations[0]
-    assert catch_op.opnum == rop.CATCH
-    guard_op = catch_op.coming_from
-    assert guard_op.is_guard()
     #
-    operations = bridge.operations = history.operations
     op = ResOperation(rop.JUMP, endliveboxes, None)
-    operations.append(op)
+    history.operations.append(op)
     #
-    old_loop = optimize.optimize_bridge(metainterp.options, old_loops, bridge,
-                                        metainterp.cpu)
-    if old_loop is None:
-        return None
-    bridge.jump_to = old_loop
-    finish_loop_or_bridge(metainterp, bridge, old_loop.operations[0], guard_op)
-    return bridge
+    #old_loop = optimize.optimize_bridge(metainterp.options, old_loops, bridge,
+    #                                    metainterp.cpu)
+    #if old_loop is None:
+    #    return None
+    # ---<temporary>---
+    target_loop = old_loops[0]
+    op.jump_target = target_loop
+    # ---</temporary>---
+    source_loop = resumekey.loop
+    guard_op = resumekey.guard_op
+    guard_op.suboperations = history.operations
+    mark_keys_in_loop(source_loop, guard_op.suboperations)
+    send_loop_to_backend(metainterp, source_loop)
+    return target_loop

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	Mon Mar 23 19:35:29 2009
@@ -295,6 +295,8 @@
     def _getrepr_(self):
         return self.value
 
+    changevalue_int = __init__
+
 class BoxPtr(Box):
     type = 'ptr'
 
@@ -315,6 +317,7 @@
         return lltype.cast_ptr_to_int(self.value)
 
     _getrepr_ = repr_pointer
+    changevalue_ptr = __init__
 
 NULLBOX = BoxPtr()
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	Mon Mar 23 19:35:29 2009
@@ -634,8 +634,9 @@
             return
         saved_pc = self.pc
         self.pc = pc
-        # XXX 'key' should be shared, either partially or if possible totally
-        key = []
+        # XXX 'resume_info' should be shared, either partially or
+        #     if possible totally
+        resume_info = []
         liveboxes = []
         for frame in self.metainterp.framestack:
             const_part = []
@@ -645,14 +646,13 @@
                     liveboxes.append(framebox)
                     framebox = None
                 const_part.append(framebox)
-            key.append((frame.jitcode, frame.pc, const_part,
-                        frame.exception_target))
+            resume_info.append((frame.jitcode, frame.pc, const_part,
+                                frame.exception_target))
         if box is not None:
             extraargs = [box] + extraargs
         guard_op = self.metainterp.history.record(opnum, extraargs, None)
         op = history.ResOperation(rop.FAIL, liveboxes, None)
-        op.key = Key(key, opnum in (rop.GUARD_EXCEPTION,
-                                    rop.GUARD_NO_EXCEPTION))
+        op.key = ResumeKey(guard_op, resume_info)
         guard_op.suboperations = [op]
         self.pc = saved_pc
         return guard_op
@@ -828,16 +828,17 @@
             return self.designate_target_loop(gmp, compiled_loop)
 
     def handle_guard_failure(self, guard_failure):
-        orig_boxes = self.initialize_state_from_guard_failure(guard_failure)
+        self.initialize_state_from_guard_failure(guard_failure)
+        key = guard_failure.key
         try:
-            if guard_failure.key.is_exception_catch:
+            if key.guard_op.opnum in (rop.GUARD_NO_EXCEPTION,
+                                      rop.GUARD_EXCEPTION):
                 self.handle_exception()
             self.interpret()
             assert False, "should always raise"
         except GenerateMergePoint, gmp:
-            compiled_bridge = self.compile_bridge(guard_failure, orig_boxes,
-                                                  gmp.argboxes)
-            return self.designate_target_loop(gmp, compiled_bridge.jump_to)
+            target_loop = self.compile_bridge(key, gmp.argboxes)
+            return self.designate_target_loop(gmp, target_loop)
 
     def designate_target_loop(self, gmp, loop):
         num_green_args = self.num_green_args
@@ -865,27 +866,23 @@
             self.debug_history = []
         return loop
 
-    def compile_bridge(self, guard_failure, original_boxes, live_arg_boxes):
-        XXX
+    def compile_bridge(self, key, live_arg_boxes):
         num_green_args = self.num_green_args
-        mp = history.ResOperation(rop.CATCH, original_boxes, None)
-        mp.coming_from = guard_failure.guard_op
-        self.history.operations.insert(0, mp)
+        greenkey = live_arg_boxes[:num_green_args]
         try:
-            old_loops = self.compiled_merge_points[
-                live_arg_boxes[:num_green_args]]
+            old_loops = self.compiled_merge_points[greenkey]
         except KeyError:
-            bridge = None
+            target_loop = None
         else:
-            bridge = compile_new_bridge(self, old_loops,
-                                        live_arg_boxes[num_green_args:])
-        if bridge is None:
+            target_loop = compile_new_bridge(self, old_loops,
+                                             live_arg_boxes[num_green_args:],
+                                             key)
+        if target_loop is None:
             raise self.ContinueRunningNormally(live_arg_boxes)
         if not we_are_translated():
-            bridge._call_history = self._debug_history
+            #bridge._call_history = self._debug_history
             self.debug_history = []
-        guard_failure.guard_op.jump_target = bridge.operations[0]
-        return bridge
+        return target_loop
 
     def get_residual_args(self, loop, args):
         if loop.specnodes is None:     # it is None only for tests
@@ -933,19 +930,19 @@
 
     def initialize_state_from_guard_failure(self, guard_failure):
         # guard failure: rebuild a complete MIFrame stack
-        if self.state.must_compile_from_failure(guard_failure):
+        if self.state.must_compile_from_failure(guard_failure.key):
             self.history = history.History(self.cpu)
         else:
             self.history = history.BlackHole(self.cpu)
-        boxes_from_frame = guard_failure.currentboxes
+        boxes_from_frame = guard_failure.args
         if 0:  # xxx guard_op.rebuild_ops is not None:
             newboxes = optimize.rebuild_boxes_from_guard_failure(
                 guard_op, self.cpu, self.history, boxes_from_frame)
         else:
             # xxx for tests only
             newboxes = boxes_from_frame
-        self.rebuild_state_after_failure(guard_failure.key.key, newboxes)
-        return boxes_from_frame
+        self.rebuild_state_after_failure(guard_failure.key.resume_info,
+                                         newboxes)
 
     def handle_exception(self):
         etype = self.cpu.get_exception()
@@ -964,12 +961,12 @@
             frame.generate_guard(frame.pc, rop.GUARD_NO_EXCEPTION, None, [])
             return False
 
-    def rebuild_state_after_failure(self, key, newboxes):
+    def rebuild_state_after_failure(self, resume_info, newboxes):
         if not we_are_translated():
             self._debug_history.append(['guard_failure', None, None])
         self.framestack = []
         nbindex = 0
-        for jitcode, pc, const_part, exception_target in key:
+        for jitcode, pc, const_part, exception_target in resume_info:
             f = self.newframe(jitcode)
             nbindex = f.setup_resume_at_op(pc, const_part, newboxes, nbindex,
                                            exception_target)
@@ -998,8 +995,9 @@
     def __init__(self, args):
         self.argboxes = args
 
-class Key(object):
-    def __init__(self, key, is_exception_catch):
-        self.key = key
+class ResumeKey(object):
+    def __init__(self, guard_op, resume_info):
+        self.resume_info = resume_info
+        self.guard_op = guard_op
         self.counter = 0
-        self.is_exception_catch = is_exception_catch
+        # self.loop = ... set in compile.py

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py	Mon Mar 23 19:35:29 2009
@@ -43,12 +43,6 @@
         return '%s%s(%s)' % (sres, self.getopname(),
                              ', '.join([str(a) for a in self.args]))
 
-    def clone(self):
-        op = ResOperation(self.opnum, self.args, self.result, self.descr)
-        op.specnodes = self.specnodes
-        op.key = self.key
-        return op
-
     def getopname(self):
         try:
             return opname[self.opnum].lower()
@@ -79,14 +73,6 @@
 # ____________________________________________________________
 
 
-class GuardFailure(object):
-    def __init__(self, key, currentboxes):
-        self.key = key
-        self.currentboxes = currentboxes
-
-# ____________________________________________________________
-
-
 class rop(object):
     """The possible names of the ResOperations."""
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py	Mon Mar 23 19:35:29 2009
@@ -502,9 +502,8 @@
                 guard_failure = cpu.execute_operations(loop, boxes)
                 loop, boxes = metainterp.handle_guard_failure(guard_failure)
 
-        def must_compile_from_failure(self, guard_failure):
-            key_holder = guard_failure.key
-            key_holder.counter += 1
-            return key_holder.counter >= self.trace_eagerness
+        def must_compile_from_failure(self, key):
+            key.counter += 1
+            return key.counter >= self.trace_eagerness
 
     return WarmEnterState



More information about the Pypy-commit mailing list