[pypy-svn] r52558 - in pypy/branch/jit-hotpath/pypy: jit/hintannotator jit/rainbow jit/rainbow/test rlib

arigo at codespeak.net arigo at codespeak.net
Sat Mar 15 16:47:56 CET 2008


Author: arigo
Date: Sat Mar 15 16:47:55 2008
New Revision: 52558

Modified:
   pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py
   pypy/branch/jit-hotpath/pypy/rlib/jit.py
Log:
Handle void variables across the jit_merge_point().


Modified: pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py	Sat Mar 15 16:47:55 2008
@@ -1,4 +1,4 @@
-from pypy.objspace.flow.model import checkgraph, copygraph
+from pypy.objspace.flow.model import checkgraph, copygraph, Constant
 from pypy.objspace.flow.model import Block, Link, SpaceOperation, Variable
 from pypy.translator.unsimplify import split_block, varoftype
 from pypy.translator.simplify import join_blocks
@@ -6,6 +6,7 @@
 from pypy.jit.hintannotator.model import SomeLLAbstractConstant, OriginFlags
 from pypy.annotation import model as annmodel
 from pypy.rpython.rtyper import LowLevelOpList
+from pypy.rpython.lltypesystem import lltype
 from pypy.rlib.jit import JitHintError
 
 
@@ -94,12 +95,14 @@
         portalopindex = portalblock.operations.index(portalop)
         # split the block just before the jit_merge_point()
         if portalopindex > 0:
-            split_block(hannotator, portalblock, portalopindex)
+            link = split_block(hannotator, portalblock, portalopindex)
+            portalblock = link.target
+            portalop = portalblock.operations[0]
         # split again, this time enforcing the order of the live vars
         # specified by the user in the jit_merge_point() call
-        _, portalblock, portalop = find_jit_merge_point(graph)
-        assert portalop is portalblock.operations[0]
-        livevars = portalop.args[1:]
+        assert portalop.opname == 'jit_merge_point'
+        livevars = [v for v in portalop.args[1:]
+                      if v.concretetype is not lltype.Void]
         link = split_block(hannotator, portalblock, 0, livevars)
         return link.target
     else:
@@ -109,17 +112,30 @@
     vars = [varoftype(v.concretetype, name=v) for v in graph.getargs()]
     newblock = Block(vars)
 
+    op = graph.startblock.operations[0]
+    assert op.opname == 'jit_merge_point'
+    assert op.args[0].value is drivercls
+    allvars = []
+    i = 0
+    for v in op.args[1:]:
+        if v.concretetype is lltype.Void:
+            allvars.append(Constant(None, concretetype=lltype.Void))
+        else:
+            allvars.append(vars[i])
+            i += 1
+    assert i == len(vars)
+
     llops = LowLevelOpList(rtyper)
     # generate ops to make an instance of DriverCls
     classdef = rtyper.annotator.bookkeeper.getuniqueclassdef(drivercls)
     s_instance = annmodel.SomeInstance(classdef)
     r_instance = rtyper.getrepr(s_instance)
     v_self = r_instance.new_instance(llops)
-    # generate ops to store the 'reds' variables on 'self'
+    # generate ops to store the 'greens' and 'reds' variables on 'self'
     num_greens = len(drivercls.greens)
     num_reds = len(drivercls.reds)
-    assert len(vars) == num_greens + num_reds
-    for name, v_value in zip(drivercls.reds, vars[num_greens:]):
+    assert len(allvars) == num_greens + num_reds
+    for name, v_value in zip(drivercls.greens + drivercls.reds, allvars):
         r_instance.setfield(v_self, name, v_value, llops)
     # generate a call to on_enter_jit(self)
     on_enter_jit_func = drivercls.on_enter_jit.im_func
@@ -128,10 +144,13 @@
     c_func = r_func.get_unique_llfn()
     llops.genop('direct_call', [c_func, v_self])
     # generate ops to reload the 'reds' variables from 'self'
-    newvars = vars[:num_greens]
-    for name, v_value in zip(drivercls.reds, vars[num_greens:]):
+    # XXX Warning!  the 'greens' variables are not reloaded.  This is
+    # a bit of a mess color-wise, and probably not useful.
+    newvars = allvars[:num_greens]
+    for name, v_value in zip(drivercls.reds, allvars[num_greens:]):
         v_value = r_instance.getfield(v_self, name, llops)
         newvars.append(v_value)
+    newvars = [v for v in newvars if v.concretetype is not lltype.Void]
     # done, fill the block and link it to make it the startblock
     newblock.operations[:] = llops
     newblock.closeblock(Link(newvars, graph.startblock))

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	Sat Mar 15 16:47:55 2008
@@ -1378,14 +1378,15 @@
         return c
 
     def decode_hp_hint_args(self, op):
-        # Returns (list-of-green-vars, list-of-red-vars).
+        # Returns (list-of-green-vars, list-of-red-vars) without Voids.
         drivercls = op.args[0].value
         numgreens = len(drivercls.greens)
         numreds = len(drivercls.reds)
         greens_v = op.args[1:1+numgreens]
         reds_v = op.args[1+numgreens:]
         assert len(reds_v) == numreds
-        return greens_v, reds_v
+        return ([v for v in greens_v if v.concretetype is not lltype.Void],
+                [v for v in reds_v if v.concretetype is not lltype.Void])
 
     def check_hp_hint_args(self, op):
         # Check the colors of the jit_merge_point() and can_enter_jit()

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py	Sat Mar 15 16:47:55 2008
@@ -352,6 +352,29 @@
             "run_machine_code 2",
             ])
 
+    def test_on_enter_jit_many_vars(self):
+        class MyJitDriver(JitDriver):
+            greens = ['void1', 'm']
+            reds = ['void2', 'n']
+            def on_enter_jit(self):
+                self.n += self.m     # doesn't make sense, just for testing
+                # note that the green 'self.m' cannot be modified
+                # (changes would not be reloaded into the 'm' var currently)
+
+        def ll_function(n, m):
+            MyJitDriver.jit_merge_point(n=n, m=m, void1=None, void2=None)
+            MyJitDriver.can_enter_jit(n=n, m=m, void1=None, void2=None)
+            hint(m, concrete=True)
+            return n + 5
+
+        res = self.run(ll_function, [2, 200], threshold=1, small=True)
+        assert res == 207
+        self.check_traces([
+            "jit_compile 200",
+            "done at hp_return",
+            "run_machine_code 200 2",
+            ])
+
     def test_hp_tlr(self):
         from pypy.jit.tl import tlr
 

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py	Sat Mar 15 16:47:55 2008
@@ -258,6 +258,9 @@
         self.check_insns(int_add=0, int_mul=0)
 
     def test_more_promotes(self):
+        class MyJitDriver(JitDriver):
+            greens = []
+            reds = ['n', 'm', 'i', 's']
         S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed))
         def ll_two(s, i, m):
             if i > 4:
@@ -279,7 +282,8 @@
             s.y = 0
             i = 0
             while i < n:
-                hint(None, global_merge_point=True)
+                MyJitDriver.jit_merge_point(n=n, m=m, i=i, s=s)
+                MyJitDriver.can_enter_jit(n=n, m=m, i=i, s=s)
                 k = ll_two(s, i, m)
                 if m & 1:
                     k *= 3
@@ -290,7 +294,7 @@
                 i += j
             return s.x + s.y * 17
 
-        res = self.interpret(ll_function, [100, 2])
+        res = self.run(ll_function, [100, 2], threshold=3)
         assert res == ll_function(100, 2)
 
     def test_mixed_merges(self):
@@ -323,22 +327,30 @@
         assert res == ll_function(6, 3, 2, 2)
 
     def test_green_across_global_mp(self):
-        py.test.skip("void vars not handled correctly")
+        class MyJitDriver(JitDriver):
+            greens = ['n1', 'n2']
+            reds = ['total', 'n3', 'n4']
         def ll_function(n1, n2, n3, n4, total):
             while n2:
-                hint(None, global_merge_point=True)
-                total += n3
-                hint(n4, concrete=True)
+                MyJitDriver.jit_merge_point(n1=n1, n2=n2, n3=n3, n4=n4,
+                                            total=total)
+                MyJitDriver.can_enter_jit(n1=n1, n2=n2, n3=n3, n4=n4,
+                                          total=total)
+                total += n4
+                total *= n2
                 hint(n3, concrete=True)
                 hint(n2, concrete=True)
                 hint(n1, concrete=True)
                 n2 -= 1
             return total
-        void = lambda s: None
-        ll_function.convert_arguments = [void, int, int, void, int]
+        def main(n2, n4, total):
+            return ll_function(None, n2, None, n4, total)
+
+        res = self.run(main, [7, 3, 100], threshold=2)
+        assert res == main(7, 3, 100)
 
-        res = self.interpret(ll_function, [None, 4, 3, None, 100], [0])
-        assert res == ll_function(None, 4, 3, None, 100)
+        res = self.run(main, [7, 3, 100], threshold=1)
+        assert res == main(7, 3, 100)
 
     def test_remembers_across_mp(self):
         def ll_function(x, flag):

Modified: pypy/branch/jit-hotpath/pypy/rlib/jit.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rlib/jit.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rlib/jit.py	Sat Mar 15 16:47:55 2008
@@ -178,6 +178,10 @@
 
     def _emulate_method_calls(cls, bookkeeper, livevars_s):
         # annotate "cls.on_enter_jit()" if it is defined
+        # on_enter_jit(self) is called with a copy of the value of the
+        # red and green variables.  The red variables can be modified
+        # in order to give hints to the JIT about the redboxes.  The
+        # green variables should not be changed.
         from pypy.annotation import model as annmodel
         if hasattr(cls, 'on_enter_jit'):
             classdef = bookkeeper.getuniqueclassdef(cls)



More information about the Pypy-commit mailing list