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

arigo at codespeak.net arigo at codespeak.net
Sun Oct 1 17:07:47 CEST 2006


Author: arigo
Date: Sun Oct  1 17:07:44 2006
New Revision: 32790

Modified:
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/test/test_promotion.py
Log:
Test and code for multiple consecutive promotion points.


Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Sun Oct  1 17:07:44 2006
@@ -10,6 +10,9 @@
 
 FOLDABLE_OPS = dict.fromkeys(lloperation.enum_foldable_ops())
 
+def debug_view(*ll_objects):
+    lloperation.llop.debug_view(lltype.Void, *ll_objects)
+
 # ____________________________________________________________
 # emit ops
 
@@ -249,7 +252,7 @@
             jitstate.split(later_builder, resumepoint, list(greens_gv))
             return True
         else:
-            return jitstate.resuming.path.pop()
+            return jitstate.resuming.path.pop().answer
 
 def collect_split(jitstate_chain, resumepoint, *greens_gv):
     greens_gv = list(greens_gv)
@@ -343,8 +346,10 @@
 
 class ResumingInfo(object):
     def __init__(self, promotion_point, gv_value, path):
+        node = PromotionPathPromote(promotion_point.promotion_path,
+                                    promotion_point, gv_value)
+        path[0] = node
         self.promotion_point = promotion_point
-        self.gv_value = gv_value
         self.path = path
 
 class PromotionPoint(object):
@@ -387,7 +392,7 @@
     def __init__(self, next):
         self.next = next
     def follow_path(self, path):
-        path.append(self.answer)
+        path.append(self)
         return self.next.follow_path(path)
 
 class PromotionPathYes(PromotionPathNode):
@@ -403,15 +408,21 @@
         self.arg = arg
 
     def follow_path(self, path):
-        path.append(self.arg)
+        path.append(self)
         return PromotionPathNo.follow_path(self, path)
-        
+
+class PromotionPathPromote(PromotionPathNode):
+    def __init__(self, next, promotion_point, gv_value):
+        self.next = next
+        self.promotion_point = promotion_point
+        self.gv_value = gv_value
+
 
 def ll_continue_compilation(promotion_point_ptr, value):
     try:
         promotion_point = cast_base_ptr_to_instance(PromotionPoint,
                                                     promotion_point_ptr)
-        path = []
+        path = [None]
         root = promotion_point.promotion_path.follow_path(path)
         gv_value = root.rgenop.genconst(value)
         resuminginfo = ResumingInfo(promotion_point, gv_value, path)
@@ -471,21 +482,27 @@
         else:
             assert jitstate.promotion_path is None
             resuming = jitstate.resuming
-            assert len(resuming.path) == 0
-            pm = resuming.promotion_point
-
-            kinds = [box.kind for box in incoming]
-            vars_gv = jitstate.curbuilder.rgenop.stop_replay(pm.switchblock,
-                                                             kinds)
-            for i in range(len(incoming)):
-                incoming[i].genvar = vars_gv[i]
-            box.genvar = resuming.gv_value
+            node = resuming.path.pop()
+            #debug_view(node, resuming, incoming)
+            assert isinstance(node, PromotionPathPromote)
+            pm = node.promotion_point
+            assert pm.promotion_path is node.next
+
+            if len(resuming.path) == 0:
+                # XXX we need to do something around the switch in the 'else'
+                # case too
+                kinds = [box.kind for box in incoming]
+                vars_gv = jitstate.curbuilder.rgenop.stop_replay(
+                    pm.switchblock,
+                    kinds)
+                for i in range(len(incoming)):
+                    incoming[i].genvar = vars_gv[i]
+                newbuilder = pm.flexswitch.add_case(node.gv_value)
+                jitstate.resuming = None
+                jitstate.promotion_path = node
+                jitstate.curbuilder = newbuilder
 
-            newbuilder = pm.flexswitch.add_case(resuming.gv_value)
-
-            jitstate.resuming = None
-            jitstate.promotion_path = pm.promotion_path
-            jitstate.curbuilder = newbuilder
+            box.genvar = node.gv_value
             enter_block(jitstate)
             return False
 
@@ -672,9 +689,9 @@
         dispatchqueue.parent_promotion_path = jitstate.promotion_path
         jitstate.promotion_path = PromotionPathYes(jitstate.promotion_path)
     else:
-        dispatchqueue.parent_resuming = resuming
-        taking = resuming.path.pop()
+        taking = resuming.path.pop().answer
         if not taking:
+            dispatchqueue.parent_resuming = resuming
             jitstate.resuming = None
     jitstate.frame = VirtualFrame(jitstate.frame, dispatchqueue)
                 
@@ -746,7 +763,9 @@
             jitstate = jitstate.next
         return return_chain    # a jitstate, which is the head of the chain
     else:
-        n = resuming.path.pop()
+        node = resuming.path.pop()
+        assert isinstance(node, PromotionPathNoWithArg)
+        n = node.arg
         for i in range(n):
             assert jitstate.resuming is None
             jitstate = jitstate.next

Modified: pypy/dist/pypy/jit/timeshifter/test/test_promotion.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_promotion.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_promotion.py	Sun Oct  1 17:07:44 2006
@@ -81,6 +81,31 @@
         assert res == 4*17 + 10
         self.check_insns(int_mul=0, int_add=1)
 
+    def test_promote_inside_call(self):
+        def ll_two(n):
+            k = hint(n, promote=True)
+            k *= 17
+            return hint(k, variable=True)
+        def ll_function(n):
+            return ll_two(n + 1) - 1
+        ll_function._global_merge_points_ = True
+
+        res = self.timeshift(ll_function, [10], [], policy=P_NOVIRTUAL)
+        assert res == 186
+        self.check_insns(int_add=1, int_mul=0, int_sub=0)
+
+    def test_two_promotions(self):
+        def ll_function(n, m):
+            n1 = hint(n, promote=True)
+            m1 = hint(m, promote=True)
+            s1 = n1 + m1
+            return hint(s1, variable=True)
+        ll_function._global_merge_points_ = True
+
+        res = self.timeshift(ll_function, [40, 2], [], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_insns(int_add=0)
+
 
     def test_method_call_nonpromote(self):
         class Base(object):



More information about the Pypy-commit mailing list