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

pedronis at codespeak.net pedronis at codespeak.net
Thu Nov 23 20:24:05 CET 2006


Author: pedronis
Date: Thu Nov 23 20:24:01 2006
New Revision: 34914

Modified:
   pypy/dist/pypy/jit/timeshifter/hrtyper.py
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/test/test_portal.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/dist/pypy/jit/timeshifter/transform.py
Log:
(arre, pedronis)

started working toward supporting returning more than one state out of red calls: introduce a collect_split after all of them
like for yellow calls. For now it always receives just one state. Next step is to have merging that can keep more than one  state
for a key, then leave code for calls will need to be changed to cope with that.

We will probably need to do something about portal calls which should not return more than one single state.



Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py	Thu Nov 23 20:24:01 2006
@@ -827,14 +827,6 @@
                   [v_jitstate     , c_index                          , c_TYPE],
                   s_result)
 
-    def translate_op_fetch_return(self, hop):
-        ts = self
-        v_jitstate = hop.llops.getjitstate()
-        return hop.llops.genmixlevelhelpercall(rtimeshift.getreturnbox,
-                                               [ts.s_JITState],
-                                               [v_jitstate   ],
-                                               ts.s_RedBox)
-
     def translate_op_is_constant(self, hop):
         hs = hop.args_s[0]
         r_arg = self.getredrepr(originalconcretetype(hs))

Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Thu Nov 23 20:24:01 2006
@@ -329,6 +329,8 @@
         for i in range(node.n):
             pending = pending.next
         pending.greens.extend(greens_gv)
+        if pending.returnbox is not None:
+            pending.frame.local_boxes.insert(0, getreturnbox(pending))
         pending.next = None
         return pending
 
@@ -337,6 +339,8 @@
         jitstate = pending
         pending = pending.next
         jitstate.greens.extend(greens_gv)   # item 0 is the return value
+        if jitstate.returnbox is not None:
+            jitstate.frame.local_boxes.insert(0, getreturnbox(jitstate))
         jitstate.resumepoint = resumepoint
         if resuming is None:
             node = jitstate.promotion_path
@@ -399,7 +403,9 @@
     return jitstate.greens[i].revealconst(T)
 
 def getreturnbox(jitstate):
-    return jitstate.returnbox
+    retbox = jitstate.returnbox
+    jitstate.returnbox = None
+    return retbox
 
 def getexctypebox(jitstate):
     return jitstate.exc_type_box
@@ -916,6 +922,8 @@
     if jitstate is not None:
         myframe = jitstate.frame
         leave_frame(jitstate)
+        jitstate.greens = []
+        jitstate.next = None
         jitstate.returnbox = myframe.local_boxes[0]
         # ^^^ fetched by a 'fetch_return' operation
     return jitstate
@@ -924,6 +932,9 @@
     jitstate = merge_returning_jitstates(jitstate, dispatchqueue)
     if jitstate is not None:
         leave_frame(jitstate)
+        jitstate.greens = []
+        jitstate.next = None        
+        jitstate.returnbox = None
     return jitstate
 
 def leave_frame(jitstate):

Modified: pypy/dist/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_portal.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_portal.py	Thu Nov 23 20:24:01 2006
@@ -221,8 +221,8 @@
 
         res = self.timeshift_from_portal(ll_function, ll_function, [5], policy=P_NOVIRTUAL)
         assert res == 10
-        self.check_insns(indirect_call=0)
+        self.check_insns(indirect_call=0) #, malloc=0)
 
         res = self.timeshift_from_portal(ll_function, ll_function, [0], policy=P_NOVIRTUAL)
         assert res == ord('2')
-        self.check_insns(indirect_call=0)
+        self.check_insns(indirect_call=0) #, malloc=0)

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Thu Nov 23 20:24:01 2006
@@ -1079,6 +1079,28 @@
         assert res == 42
         self.check_insns({})
 
+    def test_simple_red_meth(self):
+        class Base(object):
+            def m(self, n):
+                raise NotImplementedError
+            pass  # for inspect.getsource() bugs
+
+        class Concrete(Base):
+            def m(self, n):
+                return 21*n
+            pass  # for inspect.getsource() bugs
+
+        def f(flag, x):
+            if flag:
+                o = Base()
+            else:
+                o = Concrete()
+            return o.m(x)
+
+        res = self.timeshift(f, [0, 2], [0], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_insns({'int_mul': 1})        
+
     def test_compile_time_const_tuple(self):
         d = {(4, 5): 42, (6, 7): 12}
         def f(a, b):

Modified: pypy/dist/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/transform.py	Thu Nov 23 20:24:01 2006
@@ -9,7 +9,7 @@
 from pypy.translator.unsimplify import split_block, split_block_at_start
 from pypy.translator.simplify import rec_op_has_side_effects
 from pypy.translator.backendopt.ssa import SSA_to_SSI
-from pypy.translator.backendopt import support
+from pypy.translator.unsimplify import split_block
 
 
 class MergePointFamily(object):
@@ -512,16 +512,25 @@
         self.go_to_dispatcher_if(block, v_finished)
 
     def handle_red_call(self, block, pos, color='red'):
-        varsalive = self.variables_alive(block, pos+1)
+        link = split_block(self.hannotator, block, pos+1)
         op = block.operations.pop(pos)
+        assert len(block.operations) == pos
+        nextblock = link.target
+        linkargs = link.args
+        varsalive = list(linkargs)
+        
         try:
-            varsalive.remove(op.result)
-            uses_retval = True      # it will be restored by 'fetch_return'
+            index = varsalive.index(op.result)
+            uses_retval = True      # it will be restored by a restore_local
+            del varsalive[index]
+            old_v_result = linkargs.pop(index)
+            linkargs.insert(0, old_v_result)
+            v_result = nextblock.inputargs.pop(index)
+            nextblock.inputargs.insert(0, v_result)      
         except ValueError:
             uses_retval = False
-        reds, greens = self.sort_by_color(varsalive)
 
-        nextblock = self.naive_split_block(block, pos)
+        reds, greens = self.sort_by_color(varsalive)
 
         v_func = op.args[0]
         hs_func = self.hannotator.binding(v_func)
@@ -538,29 +547,17 @@
                                        resulttype = lltype.Bool)
             self.genswitch(block, v_is_constant, true  = constantblock,
                                                  false = nonconstantblock)
-            constantblock.closeblock(Link([], nextblock))
-            nonconstantblock.closeblock(Link([], nextblock))
 
         postconstantblock = self.naive_split_block(constantblock,
                                                  len(constantblock.operations))
         blockset[postconstantblock] = False
         self.make_call(constantblock, op, reds, color)
 
-        mapping = {}
-        for i, var in enumerate(reds):
-            c_index = Constant(i, concretetype=lltype.Signed)
-            newvar = self.genop(postconstantblock, 'restore_local', [c_index],
-                                result_like = var)
-            mapping[var] = newvar
-
-        if uses_retval:
-            assert not self.hannotator.binding(op.result).is_green()
-            var = op.result
-            newvar = self.genop(postconstantblock, 'fetch_return', [],
-                                result_like = var)
-            mapping[var] = newvar
-
-        nextblock.renamevariables(mapping)
+        resumepoint = self.get_resume_point(nextblock)
+        c_resumepoint = inputconst(lltype.Signed, resumepoint)
+        self.genop(postconstantblock, 'collect_split', [c_resumepoint] + greens)
+        resumeblock = self.get_resume_point_link(nextblock).target
+        postconstantblock.recloseblock(Link([], resumeblock))
 
         if nonconstantblock is not None:
             args_v = op.args[1:]
@@ -571,21 +568,13 @@
             v_res = self.genop(nonconstantblock, 'residual_%s_call' % (color,),
                                [op.args[0]], result_like = op.result)
 
-            oldvars = mapping.keys()
-            newvars = [mapping[v] for v in oldvars]
-            postconstantblock.exits[0].args = newvars
-            nextblock.inputargs = newvars
-
-            mapping2 = dict([(v, copyvar(self.hannotator, v))
-                             for v in newvars])
-            nextblock.renamevariables(mapping2)
-
-            mapping3 = {op.result: v_res}
-            nonconstantblock.exits[0].args = [mapping3.get(v, v)
-                                              for v in oldvars]
+            if uses_retval:
+                linkargs[0] = v_res
+            
+            nonconstantblock.closeblock(Link(linkargs, nextblock))
 
-        blockset[block] = True    # reachable from outside
-        blockset[nextblock] = False
+        blockset[block] = True     # reachable from outside
+        blockset[nextblock] = True # reachable from outside
         SSA_to_SSI(blockset, self.hannotator)
 
     def handle_gray_call(self, block, pos):
@@ -619,8 +608,7 @@
             newop = SpaceOperation('same_as', [v_tmp], v_real_result)
             block.operations.insert(pos+1, newop)
 
-        link = support.split_block_with_keepalive(block, pos+1,
-                                                  annotator=self.hannotator)
+        link = split_block(self.hannotator, block, pos+1)
         op1 = block.operations.pop(pos)
         assert op1 is op
         assert len(block.operations) == pos
@@ -694,8 +682,7 @@
         newop = SpaceOperation('revealconst', [v_promote], op.result)
         block.operations[i] = newop
 
-        link = support.split_block_with_keepalive(block, i,
-                                                  annotator=self.hannotator)
+        link = split_block(self.hannotator, block, i)
         nextblock = link.target
 
         reds, greens = self.sort_by_color(link.args)



More information about the Pypy-commit mailing list