[pypy-svn] r32524 - pypy/branch/timeshift-refactoring/pypy/jit/timeshifter

arigo at codespeak.net arigo at codespeak.net
Wed Sep 20 13:20:53 CEST 2006


Author: arigo
Date: Wed Sep 20 13:20:52 2006
New Revision: 32524

Modified:
   pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py
   pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py
   pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py
Log:
(arre, arigo)

Merge point support again.  Some tests pass again.


Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py	Wed Sep 20 13:20:52 2006
@@ -1,6 +1,7 @@
 import operator, weakref
 from pypy.rpython.lltypesystem import lltype, lloperation, llmemory
 from pypy.jit.timeshifter import rvalue
+from pypy.rpython.unroll import unrolling_iterable
 
 FOLDABLE_OPS = dict.fromkeys(lloperation.enum_foldable_ops())
 
@@ -234,7 +235,7 @@
     jitstate.split(later_builder, resumepoint, list(greens_gv))
 
 def dispatch_next(oldjitstate):
-    split_queue = oldjitstate.frame.split_queue
+    split_queue = oldjitstate.frame.dispatch_queue.split_queue
     if split_queue:
         jitstate = split_queue.pop()
         enter_block(jitstate)
@@ -273,7 +274,7 @@
     jitstate.exc_value_box = box
 
 def save_return(jitstate):
-    jitstate.frame.return_queue.append(jitstate)
+    jitstate.frame.dispatch_queue.return_queue.append(jitstate)
 
 def ll_gvar_from_redbox(jitstate, redbox):
     return redbox.getgenvar(jitstate.curbuilder)
@@ -283,6 +284,22 @@
 
 # ____________________________________________________________
 
+class BaseDispatchQueue(object):
+    def __init__(self):
+        self.split_queue = []      # XXX could be turned into a linked list
+        self.return_queue = []     # XXX could be turned into a linked list
+
+def build_dispatch_subclass(attrnames):
+    if len(attrnames) == 0:
+        return BaseDispatchQueue
+    attrnames = unrolling_iterable(attrnames)
+    class DispatchQueue(BaseDispatchQueue):
+        def __init__(self):
+            BaseDispatchQueue.__init__(self)
+            for name in attrnames:
+                setattr(self, name, {})     # the new dicts have various types!
+    return DispatchQueue
+
 
 class FrozenVirtualFrame(object):
     fz_backframe = None
@@ -332,10 +349,9 @@
 
 class VirtualFrame(object):
 
-    def __init__(self, backframe, split_queue, return_queue):
+    def __init__(self, backframe, dispatch_queue):
         self.backframe = backframe
-        self.split_queue = split_queue
-        self.return_queue = return_queue
+        self.dispatch_queue = dispatch_queue
         #self.local_boxes = ... set by callers
 
     def enter_block(self, incoming, memo):
@@ -357,9 +373,7 @@
             newbackframe = None
         else:
             newbackframe = self.backframe.copy(memo)
-        result = VirtualFrame(newbackframe,
-                              self.split_queue,
-                              self.return_queue)
+        result = VirtualFrame(newbackframe, self.dispatch_queue)
         result.local_boxes = [box.copy(memo) for box in self.local_boxes]
         return result
 
@@ -391,7 +405,7 @@
                                   self.exc_value_box.copy(memo),
                                   newresumepoint,
                                   newgreens)
-        self.frame.split_queue.append(later_jitstate)
+        self.frame.dispatch_queue.split_queue.append(later_jitstate)
 
     def enter_block(self, incoming, memo):
         self.frame.enter_block(incoming, memo)
@@ -411,11 +425,13 @@
         self.exc_value_box = self.exc_value_box.replace(memo)
 
 
-def enter_graph(jitstate):
-    jitstate.frame = VirtualFrame(jitstate.frame, [], [])
+def enter_graph(jitstate, DispatchQueueClass):
+    jitstate.frame = VirtualFrame(jitstate.frame, DispatchQueueClass())
+enter_graph._annspecialcase_ = 'specialize:arg(1)'
+# XXX is that too many specializations? ^^^
 
 def leave_graph_red(jitstate):
-    return_queue = jitstate.frame.return_queue
+    return_queue = jitstate.frame.dispatch_queue.return_queue
     return_cache = {}
     still_pending = []
     for jitstate in return_queue:

Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py	(original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py	Wed Sep 20 13:20:52 2006
@@ -58,6 +58,7 @@
         self.annhelper = annlowlevel.MixLevelHelperAnnotator(rtyper)
         self.timeshift_mapping = {}
         self.sigs = {}
+        self.dispatchsubclasses = {}
 
         (self.s_CodeGenerator,
          self.r_CodeGenerator) = self.s_r_instanceof(cgmodel.CodeGenerator)
@@ -226,6 +227,15 @@
             self.color_cache[id(hs)] = color
             return color
 
+    def get_dispatch_subclass(self, mergepointfamily):
+        try:
+            return self.dispatchsubclasses[mergepointfamily]
+        except KeyError:
+            attrnames = mergepointfamily.getattrnames()
+            subclass = rtimeshift.build_dispatch_subclass(attrnames)
+            self.dispatchsubclasses[mergepointfamily] = subclass
+            return subclass
+
     def insert_v_jitstate_everywhere(self, graph):
         from pypy.translator.unsimplify import varoftype
         for block in graph.iterblocks():
@@ -557,10 +567,14 @@
     # special operations inserted by the HintGraphTransformer
 
     def translate_op_enter_graph(self, hop):
+        mpfamily = hop.args_v[0].value
+        subclass = self.get_dispatch_subclass(mpfamily)
+        s_subclass = self.rtyper.annotator.bookkeeper.immutablevalue(subclass)
+        c_subclass = inputconst(lltype.Void, subclass)
         v_jitstate = hop.llops.getjitstate()
         hop.llops.genmixlevelhelpercall(rtimeshift.enter_graph,
-                                        [self.s_JITState],
-                                        [v_jitstate     ],
+                                        [self.s_JITState, s_subclass],
+                                        [v_jitstate     , c_subclass],
                                         annmodel.s_None)
 
     def translate_op_leave_graph_red(self, hop):
@@ -671,6 +685,23 @@
         hop.llops.genmixlevelhelpercall(rtimeshift.split, args_s, args_v,
                                         annmodel.s_None)
 
+    def translate_op_merge_point(self, hop):
+        mpfamily = hop.args_v[0].value
+        attrname = hop.args_v[1].value
+        DispatchQueueSubclass = self.get_dispatch_subclass(mpfamily)
+
+        def merge_point(jitstate, *key):
+            dispatch_queue = jitstate.frame.dispatch_queue
+            assert isinstance(dispatch_queue, DispatchQueueSubclass)
+            states_dic = getattr(dispatch_queue, attrname)
+            return rtimeshift.retrieve_jitstate_for_merge(states_dic,
+                                                          jitstate, key)
+        v_jitstate = hop.llops.getjitstate()
+        return hop.llops.genmixlevelhelpercall(merge_point,
+                             [self.s_JITState] + hop.args_s[2:],
+                             [v_jitstate     ] + hop.args_v[2:],
+                             annmodel.SomeBool())
+
     def translate_op_save_return(self, hop):
         v_jitstate = hop.llops.getjitstate()
         return hop.llops.genmixlevelhelpercall(rtimeshift.save_return,

Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py	(original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py	Wed Sep 20 13:20:52 2006
@@ -1,5 +1,5 @@
 from pypy.objspace.flow.model import Variable, Constant, Block, Link
-from pypy.objspace.flow.model import SpaceOperation
+from pypy.objspace.flow.model import SpaceOperation, mkentrymap
 from pypy.annotation        import model as annmodel
 from pypy.jit.hintannotator import model as hintmodel
 from pypy.rpython.lltypesystem import lltype, llmemory
@@ -9,20 +9,42 @@
 from pypy.translator.backendopt.ssa import SSA_to_SSI
 
 
+class MergePointFamily(object):
+    def __init__(self):
+        self.count = 0
+    def add(self):
+        result = self.count
+        self.count += 1
+        return 'mp%d' % result
+    def getattrnames(self):
+        return ['mp%d' % i for i in range(self.count)]
+
+
 class HintGraphTransformer(object):
 
     def __init__(self, hannotator, graph):
         self.hannotator = hannotator
         self.graph = graph
         self.resumepoints = {}
+        self.mergepointfamily = MergePointFamily()
+        self.c_mpfamily = inputconst(lltype.Void, self.mergepointfamily)
 
     def transform(self):
+        mergepoints = list(self.enumerate_merge_points())
         self.insert_save_return()
         self.insert_splits()
+        for block in mergepoints:
+            self.insert_merge(block)
         self.insert_dispatcher()
         self.insert_enter_graph()
         self.insert_leave_graph()
 
+    def enumerate_merge_points(self):
+        entrymap = mkentrymap(self.graph)
+        for block, links in entrymap.items():
+            if len(links) > 1 and block is not self.graph.returnblock:
+                yield block
+
     # __________ helpers __________
 
     def genop(self, block, opname, args, result_type=None):
@@ -41,7 +63,10 @@
             raise TypeError("result_type=%r" % (result_type,))
 
         spaceop = SpaceOperation(opname, args, v_res)
-        block.operations.append(spaceop)
+        if isinstance(block, list):
+            block.append(spaceop)
+        else:
+            block.operations.append(spaceop)
         return v_res
 
     def genswitch(self, block, v_exitswitch, false, true):
@@ -65,6 +90,16 @@
         newblock.closeblock(bridge)
         return newblock
 
+    def naive_split_block(self, block, position):
+        newblock = Block([])
+        newblock.operations = block.operations[position:]
+        del block.operations[position:]
+        newblock.exitswitch = block.exitswitch
+        block.exitswitch = None
+        newblock.recloseblock(*block.exits)
+        block.recloseblock(Link([], newblock))
+        return newblock
+
     def sort_by_color(self, vars):
         reds = []
         greens = []
@@ -164,6 +199,36 @@
             self.resumepoints[block] = reenter_link
         return reenter_link.exitcase
 
+    def insert_merge(self, block):
+        reds, greens = self.sort_by_color(block.inputargs)
+        nextblock = self.naive_split_block(block, 0)
+
+        self.genop(block, 'save_locals', reds)
+        mp   = self.mergepointfamily.add()
+        c_mp = inputconst(lltype.Void, mp)
+        v_finished_flag = self.genop(block, 'merge_point',
+                                     [self.c_mpfamily, c_mp] + greens,
+                                     result_type = lltype.Bool)
+        block.exitswitch = v_finished_flag
+        [link_f] = block.exits
+        link_t = Link([inputconst(lltype.Void, None)], self.graph.returnblock)
+        link_f.exitcase = False
+        link_t.exitcase = True
+        block.recloseblock(link_f, link_t)
+
+        restoreops = []
+        mapping = {}
+        for i, v in enumerate(reds):
+            c = inputconst(lltype.Signed, i)
+            v1 = self.genop(restoreops, 'restore_local', [c],
+                            result_type = v)
+            mapping[v] = v1
+        nextblock.renamevariables(mapping)
+        nextblock.operations[:0] = restoreops
+
+        SSA_to_SSI({block    : True,    # reachable from outside
+                    nextblock: False}, self.hannotator)
+
     def insert_dispatcher(self):
         if self.resumepoints:
             block = self.before_return_block()
@@ -189,7 +254,7 @@
         self.graph.startblock.isstartblock = False
         self.graph.startblock = entryblock
 
-        self.genop(entryblock, 'enter_graph', [])
+        self.genop(entryblock, 'enter_graph', [self.c_mpfamily])
 
     def insert_leave_graph(self):
         block = self.before_return_block()



More information about the Pypy-commit mailing list