[pypy-svn] r23461 - in pypy/dist/pypy/jit: . test

ac at codespeak.net ac at codespeak.net
Fri Feb 17 19:49:51 CET 2006


Author: ac
Date: Fri Feb 17 19:49:50 2006
New Revision: 23461

Modified:
   pypy/dist/pypy/jit/hinttimeshift.py
   pypy/dist/pypy/jit/rtimeshift.py
   pypy/dist/pypy/jit/test/test_hint_timeshift.py
Log:
(pedronis, arre)
Make splitting on a red variable and merging work.

Test test_loop_merging passes now.

The code needs cleanup. For now we don't drop the already unrolled
code blocks, this may need to change later.

It should be possible to extend what we have, after cleanup, to deal
with direct_calls.



Modified: pypy/dist/pypy/jit/hinttimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/hinttimeshift.py	(original)
+++ pypy/dist/pypy/jit/hinttimeshift.py	Fri Feb 17 19:49:50 2006
@@ -11,62 +11,139 @@
 
 # ___________________________________________________________
 
+def define_queue_in_state(rtyper, s_item, fieldname):
+    queue_def = listdef.ListDef(None,
+                                s_item)
+    queue_def.resize()
+    queue_def.mutate()
+
+    s_queue = annmodel.SomeList(queue_def)
+
+    r_queue = rtyper.getrepr(s_queue)
+    r_queue.setup()
+    QUEUE = r_queue.lowleveltype
+
+    def ll_get_queue(questate):
+        pass
+    def _ll_get_queue(questate):
+        return getattr(questate, fieldname)
+
+    llgetq = ll_get_queue
+
+    def ll_get_queue_annotation(queustate_s):
+        return s_queue
+
+    llgetq.compute_result_annotation = ll_get_queue_annotation
+
+    def ll_get_queue_specialize(hop):
+        return hop.gendirectcall(_ll_get_queue, hop.args_v[0])
+
+    llgetq.specialize = ll_get_queue_specialize
+
+    return s_queue, QUEUE, ll_get_queue
+ 
+
 class HintTimeshift(object):
     
     def __init__(self, hannotator, rtyper):
         self.hannotator = hannotator
         self.rtyper = rtyper
         self.hrtyper = HintRTyper(hannotator, self)
+        self.latestexitindex = -1
 
+        getrepr = self.rtyper.getrepr
+
+        box_list_def = listdef.ListDef(None, annmodel.SomePtr(REDBOX_PTR))
+        box_list_def.mutate()
+        self.s_box_list = annmodel.SomeList(box_list_def)
+        self.r_box_list = getrepr(self.s_box_list)
+        self.r_box_list.setup()
+
+        box_accum_def = listdef.ListDef(None, annmodel.SomePtr(REDBOX_PTR))
+        box_accum_def.mutate()
+        box_accum_def.resize()
+        self.s_box_accum = annmodel.SomeList(box_accum_def)
+        self.r_box_accum = getrepr(self.s_box_accum)
+        self.r_box_accum.setup()
 
-        # XXX refactor this more nicely
         s_return_info = annmodel.SomeTuple([annmodel.SomePtr(rgenop.LINK),
                                            annmodel.SomePtr(REDBOX_PTR)])
 
-        returrn_queue_def = listdef.ListDef(None,
-                                            s_return_info)
-        returrn_queue_def.resize()
-        returrn_queue_def.mutate()
-        
-        s_return_queue = annmodel.SomeList(returrn_queue_def)
-        
-        r_return_queue = rtyper.getrepr(s_return_queue)
-        r_return_queue.setup()
-        RETURN_QUEUE = r_return_queue.lowleveltype
-
-        def ll_get_return_queue(questate):
-            pass
-        def _ll_get_return_queue(questate):
-            return questate.return_queue
-
-        llgetq = ll_get_return_queue
+        defs = define_queue_in_state(rtyper, s_return_info, 'return_queue')
+        s_return_queue, RETURN_QUEUE, ll_get_return_queue = defs
 
-        def ll_get_return_queue_annotation(queustate_s):
-            return s_return_queue
+        s_split_info = annmodel.SomeTuple([annmodel.SomeInteger(),
+                                           annmodel.SomePtr(STATE_PTR),
+                                           self.s_box_list])
 
-        llgetq.compute_result_annotation = ll_get_return_queue_annotation
+        defs = define_queue_in_state(rtyper, s_split_info, 'split_queue')
+        s_split_queue, SPLIT_QUEUE, ll_get_split_queue = defs        
 
-        def ll_get_return_queue_specialize(hop):
-            return hop.gendirectcall(_ll_get_return_queue, hop.args_v[0])
-
-        llgetq.specialize = ll_get_return_queue_specialize
 
         def ll_newstate():
             questate = lltype.malloc(QUESTATE)
             questate.return_queue = RETURN_QUEUE.TO.ll_newlist(0)
+            questate.split_queue = SPLIT_QUEUE.TO.ll_newlist(0)
             return questate
+
+        def ll_copystate(questate):
+            newquestate = lltype.malloc(QUESTATE)
+            newquestate.return_queue = questate.return_queue
+            newquestate.split_queue = questate.split_queue
+            basestate = questate.basestate
+            newbasestate = newquestate.basestate
+            newbasestate.curblock = basestate.curblock
+            newbasestate.curoutgoinglink = basestate.curoutgoinglink
+            newbasestate.curvalue = basestate.curvalue
+            return newquestate
         
-        QUESTATE = lltype.GcStruct("quejistate",
+        QUESTATE = lltype.GcStruct("quejitstate",
                                    ('basestate', STATE),
                                    ("return_queue", RETURN_QUEUE),
+                                   ("split_queue", SPLIT_QUEUE),                                   
                                    adtmeths = {
             'll_get_return_queue': ll_get_return_queue,
+            'll_get_split_queue': ll_get_split_queue,
             'll_newstate': ll_newstate,
+            'll_copystate': ll_copystate,
             'll_basestate': lambda questate: questate.basestate})
 
         self.s_return_queue = s_return_queue # for the test
         self.QUESTATE_PTR = lltype.Ptr(QUESTATE)
-                
+
+    def getexitindex(self, link, inputargs, args_r):
+        self.latestexitindex += 1
+        v_jitstate = flowmodel.Variable('jitstate')
+        v_jitstate.concretetype = STATE_PTR
+        v_boxes = flowmodel.Variable('boxes')
+        v_boxes.concretetype = self.r_box_accum.lowleveltype
+      
+        reentry_block = flowmodel.Block([v_jitstate, v_boxes])
+
+        llops = HintLowLevelOpList(self, None)
+
+        reenter_vars = [v_jitstate]
+        for var in link.args[1:]:
+            i = inputargs.index(var)
+            r = args_r[i]
+            v_box = self.read_out_box(llops, v_boxes, i)
+            if isinstance(r, RedRepr):
+                reenter_vars.append(v_box)
+            else:
+                c_TYPE = rmodel.inputconst(lltype.Void,
+                                           r.lowleveltype)
+                v_value = llops.gendirectcall(REDBOX_PTR.TO.ll_getvalue,
+                                              v_box, c_TYPE)
+                reenter_vars.append(v_value)
+
+        reenter_link = flowmodel.Link(reenter_vars, link.target)
+        reentry_block.operations[:] = llops
+        reentry_block.closeblock(reenter_link)
+
+        from_dispatch =flowmodel.Link([None, None], reentry_block)
+        self.dispatch_to.append((self.latestexitindex, from_dispatch))        
+        return self.latestexitindex
+
     def timeshift(self):
         for graph in self.hannotator.translator.graphs:
             self.timeshift_graph(graph)
@@ -75,6 +152,7 @@
 
     def timeshift_graph(self, graph):
         self.graph = graph
+        self.dispatch_to = []
         entering_links = flowmodel.mkentrymap(graph)
 
         originalblocks = list(graph.iterblocks())
@@ -119,10 +197,7 @@
                 if link.target.operations != ():
                     link.args.insert(0, v_jitstate)
                 elif len(link.args) == 1:
-                    link.args[0] = v_jitstate
-                    v_returnjitstate = flowmodel.Variable('jitstate')
-                    self.hannotator.bindings[v_returnjitstate] = s_JITState
-                    link.target.inputargs = [v_returnjitstate]
+                    assert False, "the return block should not be seen"
                     
     def insert_before_block(self, block, entering_links, closeblock=True):
         newinputargs = []
@@ -145,17 +220,41 @@
             newblock.closeblock(bridge)
         return newblock
                                                          
+    def read_out_box(self, llops, v_boxes, i):
+        c_dum_nocheck = rmodel.inputconst(lltype.Void, rlist.dum_nocheck)
+        c_i = rmodel.inputconst(lltype.Signed, i)
+        v_box = llops.gendirectcall(rlist.ll_getitem_nonneg,
+                                    c_dum_nocheck,
+                                    v_boxes,
+                                    c_i)
+        return v_box
+
+    def insert_read_out_boxes(self, bridge, llops, v_newjitstate, v_boxes, args_r, newinputargs):
+        newinputargs2 = [v_newjitstate]
+        if bridge.target.operations == (): # special case the return block
+            assert False, "the return block should not be seen"
+        else:
+            i = 0
+            for r, newvar in zip(args_r[1:], newinputargs[1:]):
+                if isinstance(r, RedRepr):
+                    newinputargs2.append(self.read_out_box(llops, v_boxes, i))
+                    i += 1
+                else:
+                    newinputargs2.append(newvar)
+
+        # patch bridge
+        bridge.args = newinputargs2 # patch the link
+
+ 
     def insert_bookkeeping_enter(self, block, before_block, nentrylinks):
         newinputargs = before_block.inputargs
         args_r = []
         for var in newinputargs:
-            hs = self.hannotator.bindings[var]
-            args_r.append(self.hrtyper.getrepr(hs))
+            args_r.append(self.hrtyper.bindingrepr(var))
             
         llops = HintLowLevelOpList(self, None)
 
-        s_box_list = annmodel.SomeList(listdef.ListDef(None,
-                                                       annmodel.SomePtr(REDBOX_PTR)))
+
         TYPES = []
         boxes_v = []
         for r, newvar in zip(args_r, newinputargs):
@@ -164,9 +263,8 @@
                 TYPES.append(r.original_concretetype)                
         getrepr = self.rtyper.getrepr
 
-        r_box_list = getrepr(s_box_list)
-        r_box_list.setup()        
-        v_boxes = rlist.newlist(llops, r_box_list, boxes_v)
+        # XXX factor this out too!
+        v_boxes = rlist.newlist(llops, self.r_box_list, boxes_v)
         c_TYPES = rmodel.inputconst(VARLIST, make_types_const(TYPES))        
 
 
@@ -177,55 +275,26 @@
 
 
         # fill the block with logic
-        v_newjitstate = enter_block_logic(args_r, newinputargs,
-                                          llops,
-                                          s_box_list, v_boxes,
-                                          c_TYPES)
-
-        def read_out_box(i):
-            c_dum_nocheck = rmodel.inputconst(lltype.Void, rlist.dum_nocheck)
-            c_i = rmodel.inputconst(lltype.Signed, i)
-            v_box = llops.gendirectcall(rlist.ll_getitem_nonneg,
-                                        c_dum_nocheck,
-                                        v_boxes,
-                                        c_i)
-            return v_box
-            
+        enter_block_logic(args_r, newinputargs,
+                          before_block,
+                          llops,
+                          v_boxes,
+                          c_TYPES)
+
 
-        bridge = before_block.exits[0]
-        newinputargs2 = [v_newjitstate]
-        if bridge.target.operations == (): # special case the return block
-            # XXX maybe better to return a tuple (state, value)?
-            c_curvalue = rmodel.inputconst(lltype.Void, "curvalue")
-            if isinstance(args_r[1], GreenRepr):
-                v_value = llops.gendirectcall(rtimeshift.REDBOX.ll_make_from_const,
-                                              newinputargs[1])
-            else:
-                v_value = read_out_box(0)
-            llops.genop('setfield', [v_newjitstate, c_curvalue, v_value])
-        else:
-            i = 0
-            for r, newvar in zip(args_r[1:], newinputargs[1:]):
-                if isinstance(r, RedRepr):
-                    newinputargs2.append(read_out_box(i))
-                    i += 1
-                else:
-                    newinputargs2.append(newvar)
 
-        # patch before block and bridge
-        before_block.operations[:] = llops
-        bridge.args = newinputargs2 # patch the link
 
-    def bookkeeping_enter_simple(self, args_r, newinputargs, llops, s_box_list, v_boxes,
+    def bookkeeping_enter_simple(self, args_r, newinputargs, before_block, llops, v_boxes,
                                 c_TYPES):
-        v_newjiststate = llops.genmixlevelhelpercall(rtimeshift.enter_block,
-                             [annmodel.SomePtr(STATE_PTR), s_box_list,
+        v_newjitstate = llops.genmixlevelhelpercall(rtimeshift.enter_block,
+                             [annmodel.SomePtr(STATE_PTR), self.s_box_list,
                               annmodel.SomePtr(VARLIST)],
                              [newinputargs[0], v_boxes, c_TYPES])
-        return v_newjiststate
-        
-
 
+        bridge = before_block.exits[0]
+        self.insert_read_out_boxes(bridge, llops, v_newjitstate, v_boxes, args_r, newinputargs)
+        before_block.operations[:] = llops
+        
     # insert before join blocks a block with:
     # key = (<tuple-of-green-values>)
     # boxes = [<rest-of-redboxes>]
@@ -236,7 +305,7 @@
     # ll_retrieve_jitstate_for_merge is supposed to use the "constant" dict as cache
     # mapping green values combinations to frozen states for red boxes values
     # and generated blocks
-    def bookkeeping_enter_for_join(self, args_r, newinputargs, llops, s_box_list, v_boxes,
+    def bookkeeping_enter_for_join(self, args_r, newinputargs, before_block, llops, v_boxes,
                                   c_TYPES):
         getrepr = self.rtyper.getrepr        
         items_s = []
@@ -253,7 +322,7 @@
 
         s_key_tuple = annmodel.SomeTuple(items_s)
   
-        s_dict_value = annmodel.SomeTuple([s_box_list,
+        s_dict_value = annmodel.SomeTuple([self.s_box_list,
                                            annmodel.SomePtr(rgenop.BLOCK)])
         s_state_dic = annmodel.SomeDict(dictdef.DictDef(None,
                                                         s_key_tuple,
@@ -271,13 +340,58 @@
         v_key = rtuple.newtuple(llops, r_key, key_v)
 
 
+        v_oldjitstate = newinputargs[0]
 
-        v_newjiststate = llops.genmixlevelhelpercall(rtimeshift.retrieve_jitstate_for_merge,
-                             [s_state_dic, annmodel.SomePtr(STATE_PTR), s_key_tuple, s_box_list,
+        v_newjitstate = llops.genmixlevelhelpercall(rtimeshift.retrieve_jitstate_for_merge,
+                             [s_state_dic, annmodel.SomePtr(STATE_PTR), s_key_tuple, self.s_box_list,
                               annmodel.SomePtr(VARLIST)],
-                             [c_state_dic, newinputargs[0], v_key, v_boxes, c_TYPES])
-        return v_newjiststate
+                             [c_state_dic, v_oldjitstate, v_key, v_boxes, c_TYPES])
+
+        v_continue = llops.genop('ptr_nonzero', [v_newjitstate], resulttype=lltype.Bool)
+
+        v_newjitstate2 = flowmodel.Variable(v_newjitstate)
+        v_newjitstate2.concretetype = STATE_PTR
+        v_boxes2 = flowmodel.Variable(v_boxes)
+        v_boxes2.concretetype = self.r_box_list.lowleveltype
+
+
+        
+        read_boxes_block_vars = [v_newjitstate2, v_boxes2]
+        for greenvar in key_v:
+            greenvar2 = flowmodel.Variable(greenvar)
+            greenvar2.concretetype = greenvar.concretetype
+            read_boxes_block_vars.append(greenvar2)
+
+        read_boxes_block = flowmodel.Block(read_boxes_block_vars)
+        to_read_boxes_block = flowmodel.Link([v_newjitstate, v_boxes] + key_v, read_boxes_block)
+        to_read_boxes_block.exitcase = to_read_boxes_block.llexitcase = True
+        to_dispatch_block = flowmodel.Link([v_oldjitstate], self.dispatchblock)
+        to_dispatch_block.exitcase = to_dispatch_block.llexitcase = False
         
+        target = before_block.exits[0].target
+        before_block.operations[:] = llops        
+        before_block.exitswitch = v_continue
+        before_block.recloseblock(to_dispatch_block, to_read_boxes_block)
+
+        llops = HintLowLevelOpList(self, None)
+
+        newinputargs2 = [v_newjitstate2]
+        i = 0
+        j = 0
+        for r in args_r[1:]:
+            if isinstance(r, RedRepr):
+                newinputargs2.append(self.read_out_box(llops, v_boxes2, i))
+                i += 1
+            else:
+                newinputargs2.append(read_boxes_block_vars[j+2])
+                j += 1
+
+        read_boxes_block.operations[:] = llops
+
+        to_target = flowmodel.Link(newinputargs2, target)
+
+        read_boxes_block.closeblock(to_target)
+
         
     def insert_bookkeeping_leave_block(self, block, entering_links):
         # XXX wrong with exceptions as much else
@@ -290,6 +404,7 @@
             if isinstance(v, flowmodel.Variable):
                 if v not in renamemap:
                     vprime = renamemap[v] = flowmodel.Variable(v)
+                    self.hannotator.bindings[vprime] = self.hannotator.bindings[v]
                     vprime.concretetype = v.concretetype
                     inargs.append(v)
 
@@ -299,6 +414,7 @@
         newlinks = []
 
         v_newjitstate = flowmodel.Variable('jitstate')
+        self.hannotator.bindings[v_newjitstate] = s_JITState
         v_newjitstate.concretetype = STATE_PTR
 
         def rename_on_link(v):
@@ -311,6 +427,7 @@
             for v in link.args:
                 introduce(v)
             newlink =  link.copy(rename_on_link)
+            newlink.llexitcase = newlink.exitcase # sanitize the link llexitcase
             newlinks.append(newlink)
             target = link.target
             # update entering_links as necessary
@@ -322,24 +439,58 @@
 
         inputargs = [rename(v) for v in inargs]
         newblock = flowmodel.Block(inputargs)
-        newblock.exitswitch = rename(block.exitswitch)
         newblock.closeblock(*newlinks)
             
         inlink = flowmodel.Link(inargs, newblock)
-
+        oldexitswitch = block.exitswitch
         block.exitswitch = None
         block.recloseblock(inlink)
 
         llops = HintLowLevelOpList(self, None)
+        if len(newblock.exits) == 1 or isinstance(self.hrtyper.bindingrepr(oldexitswitch), GreenRepr):
+            newblock.exitswitch = rename(oldexitswitch)
+            v_res = llops.genmixlevelhelpercall(rtimeshift.leave_block,
+                                                [annmodel.SomePtr(STATE_PTR)],
+                                                [rename(orig_v_jitstate)])     
+
+            llops.append(flowmodel.SpaceOperation('same_as',
+                                   [v_res],
+                                   v_newjitstate))
+        else:
+            args_r = []
+            boxes_v = []
+            for var in inputargs[1:]:
+                r = self.hrtyper.bindingrepr(var)
+                args_r.append(r)
+                if isinstance(r, RedRepr):
+                    boxes_v.append(var)
+                elif isinstance(r, GreenRepr):
+                    boxes_v.append(llops.gendirectcall(rtimeshift.REDBOX.ll_make_from_const, var))
+                else:
+                    raise RuntimeError('Unsupported boxtype')
+            
+            getrepr = self.rtyper.getrepr
 
-        v_res = llops.genmixlevelhelpercall(rtimeshift.leave_block,
-                                            [annmodel.SomePtr(STATE_PTR)],
-                                            [rename(orig_v_jitstate)])     
-
-        llops.append(flowmodel.SpaceOperation('same_as',
-                               [v_res],
-                               v_newjitstate))
-
+            v_boxes = rlist.newlist(llops, self.r_box_list, boxes_v)
+            false_exit = [exit for exit in newblock.exits if exit.exitcase is False][0]
+            exitindex = self.getexitindex(false_exit, inputargs[1:], args_r)
+            c_exitindex = rmodel.inputconst(lltype.Signed, exitindex)
+            v_jitstate = rename(orig_v_jitstate)
+            v_quejitstate = llops.genop('cast_pointer', [v_jitstate],
+                                        resulttype=self.QUESTATE_PTR)
+            v_res = llops.genmixlevelhelpercall(rtimeshift.leave_block_split,
+                                                [annmodel.SomePtr(self.QUESTATE_PTR),
+                                                 annmodel.SomePtr(REDBOX_PTR),
+                                                 annmodel.SomeInteger(),
+                                                 self.s_box_list],
+                                                [v_quejitstate,
+                                                 rename(oldexitswitch),
+                                                 c_exitindex,
+                                                 v_boxes])
+            llops.append(flowmodel.SpaceOperation('same_as',
+                                                  [inputargs[0]],
+                                                  v_newjitstate))
+            newblock.exitswitch = v_res
         newblock.operations[:] = llops
 
     def insert_return_bookkeeping(self, before_returnblock):
@@ -366,24 +517,20 @@
         dispatchblock = self.dispatchblock
         [v_jitstate] = dispatchblock.inputargs
         llops = HintLowLevelOpList(self, None)
-        s_box_list = annmodel.SomeList(listdef.ListDef(None,
-                                                       annmodel.SomePtr(REDBOX_PTR)))
-        getrepr = self.rtyper.getrepr
 
-        r_box_list = getrepr(s_box_list)
-        r_box_list.setup()        
-        v_boxes = rlist.newlist(llops, r_box_list, [])
+
+        v_boxes = rlist.newlist(llops, self.r_box_accum, [])
 
         v_quejitstate = llops.genop('cast_pointer', [v_jitstate],
                                     resulttype=self.QUESTATE_PTR)
         
         v_next = llops.genmixlevelhelpercall(rtimeshift.dispatch_next,
-                     [annmodel.SomePtr(self.QUESTATE_PTR), s_box_list],
+                     [annmodel.SomePtr(self.QUESTATE_PTR), self.s_box_accum],
                      [v_quejitstate, v_boxes])
 
         dispatchblock.operations[:] = llops
 
-        dispatch_to = []
+        dispatch_to = self.dispatch_to
         finishedlink = flowmodel.Link([v_jitstate], returnblock)
         dispatch_to.append(('default', finishedlink))
 
@@ -393,7 +540,12 @@
             dispatchblock.exitswitch = v_next
             exitlinks = []
             for case, link in dispatch_to:
-                link.exitcase = link.llexitcase = case
+                link.exitcase =  case
+                if case != 'default':
+                    link.llexitcase = case
+                    link.args = [v_jitstate, v_boxes]
+                else:
+                    link.llexitcase = None
                 exitlinks.append(link)
             dispatchblock.closeblock(*exitlinks)
 

Modified: pypy/dist/pypy/jit/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/rtimeshift.py	Fri Feb 17 19:49:50 2006
@@ -180,6 +180,7 @@
             ll_getvalue(newbox, lltype.Signed)):
             continue
         # Missmatch. Generalize to a var
+        break
     else:
         rgenop.closelink(jitstate.curoutgoinglink, incoming, oldblock)
         return lltype.nullptr(STATE)
@@ -226,6 +227,22 @@
     jitstate.curoutgoinglink = rgenop.closeblock1(jitstate.curblock)
     return jitstate
 
+def leave_block_split(quejitstate, switchredbox, exitindex, redboxes):
+    jitstate = lltype.cast_pointer(STATE_PTR, quejitstate)
+    if not switchredbox.isvar:
+        jitstate.curoutgoinglink = rgenop.closeblock1(jitstate.curblock)        
+        return switchredbox.ll_getvalue(lltype.Bool)
+    exitgvar = switchredbox.genvar
+    linkpair = rgenop.closeblock2(jitstate.curblock, exitgvar)    
+    false_link, true_link = linkpair.item0, linkpair.item1
+    later_jitstate = quejitstate.ll_copystate()
+    later_jitstate = lltype.cast_pointer(STATE_PTR, later_jitstate)
+    jitstate.curoutgoinglink = true_link
+    later_jitstate.curoutgoinglink = false_link
+    quejitstate.ll_get_split_queue().append((exitindex, later_jitstate, redboxes))
+    return True
+    
+
 def schedule_return(jitstate, redbox):
     return_queue = jitstate.ll_get_return_queue()
     curoutgoinglink = jitstate.ll_basestate().curoutgoinglink
@@ -234,6 +251,16 @@
 novars = lltype.malloc(VARLIST.TO, 0)
 
 def dispatch_next(jitstate, outredboxes):
+    basestate = jitstate.ll_basestate()
+    split_queue = jitstate.ll_get_split_queue()
+    if split_queue:
+        exitindex, later_jitstate, redboxes = split_queue.pop()
+        basestate.curblock = later_jitstate.curblock
+        basestate.curoutgoinglink = later_jitstate.curoutgoinglink
+        basestate.curvalue = later_jitstate.curvalue
+        for box in redboxes:
+            outredboxes.append(box)
+        return exitindex
     return_queue = jitstate.ll_get_return_queue()
     basestate = jitstate.ll_basestate()
     first_redbox = return_queue[0][1]

Modified: pypy/dist/pypy/jit/test/test_hint_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_timeshift.py	(original)
+++ pypy/dist/pypy/jit/test/test_hint_timeshift.py	Fri Feb 17 19:49:50 2006
@@ -162,7 +162,6 @@
     assert insns == {}
 
 def test_loop_merging():
-    py.test.skip('Work in progress')
     def ll_function(x, y):
         tot = 0
         while x:
@@ -171,4 +170,20 @@
         return tot
     insns, res = timeshift(ll_function, [7, 2], [])
     assert res == 14
-    # assert insns == {}
+    assert insns['int_add'] == 2
+    assert insns['int_is_true'] == 2
+
+    insns, res = timeshift(ll_function, [7, 2], [0])
+    assert res == 14
+    assert insns['int_add'] == 2
+    assert insns['int_is_true'] == 1
+
+    insns, res = timeshift(ll_function, [7, 2], [1])
+    assert res == 14
+    assert insns['int_add'] == 1
+    assert insns['int_is_true'] == 2
+
+    insns, res = timeshift(ll_function, [7, 2], [0, 1])
+    assert res == 14
+    assert insns['int_add'] == 1
+    assert insns['int_is_true'] == 1



More information about the Pypy-commit mailing list