[pypy-svn] r51841 - in pypy/branch/jit-refactoring/pypy/jit/rainbow: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Mon Feb 25 00:09:19 CET 2008


Author: cfbolz
Date: Mon Feb 25 00:09:17 2008
New Revision: 51841

Added:
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_promotion.py   (contents, props changed)
Modified:
   pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
Log:
oops, forgot to svn add the promotion tests. A lot of them pass. Some other small changes.


Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py	Mon Feb 25 00:09:17 2008
@@ -638,6 +638,8 @@
             self.emit(pos)
             self.register_greenvar(op.result)
             return
+        elif kind == "residual":
+            XXX
         targets = dict(self.graphs_from(op))
         assert len(targets) == 1
         targetgraph, = targets.values()

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py	Mon Feb 25 00:09:17 2008
@@ -64,7 +64,7 @@
         interpreter.newjitstate(jitstate)
         interpreter.frame.pc = self.pc
         interpreter.frame.bytecode = self.bytecode
-        interpreter.frame.local_green = jitstate.greens
+        interpreter.frame.local_green = []
         jitstate.frame.dispatchqueue = dispatchqueue
         interpreter.bytecode_loop()
         finaljitstate = interpreter.jitstate
@@ -226,7 +226,6 @@
     def get_redarg(self):
         return self.frame.local_boxes[self.load_2byte()]
 
-
     def get_greenkey(self):
         keydescnum = self.load_2byte()
         if keydescnum == -1:

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py	Mon Feb 25 00:09:17 2008
@@ -13,7 +13,7 @@
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.module.support import LLSupport
 from pypy.annotation import model as annmodel
-from pypy.objspace.flow.model import summary
+from pypy.objspace.flow.model import summary, Variable
 from pypy.rlib.jit import hint
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy import conftest
@@ -212,6 +212,28 @@
         for opname, count in counts.items():
             assert self.insns.get(opname, 0) == count
 
+    def check_oops(self, expected=None, **counts):
+        if not self.on_llgraph:
+            return
+        oops = {}
+        for block in self.residual_graph.iterblocks():
+            for op in block.operations:
+                if op.opname == 'direct_call':
+                    f = getattr(op.args[0].value._obj, "_callable", None)
+                    if hasattr(f, 'oopspec'):
+                        name, _ = f.oopspec.split('(', 1)
+                        oops[name] = oops.get(name, 0) + 1
+        if expected is not None:
+            assert oops == expected
+        for name, count in counts.items():
+            assert oops.get(name, 0) == count
+    def check_flexswitches(self, expected_count):
+        count = 0
+        for block in self.residual_graph.iterblocks():
+            if (isinstance(block.exitswitch, Variable) and
+                block.exitswitch.concretetype is lltype.Signed):
+                count += 1
+        assert count == expected_count
 
 class SimpleTests(InterpretationTest):
     def test_simple_fixed(self):

Added: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_promotion.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_promotion.py	Mon Feb 25 00:09:17 2008
@@ -0,0 +1,414 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.rainbow.test.test_interpreter import InterpretationTest
+from pypy.jit.rainbow.test.test_interpreter import StopAtXPolicy
+from pypy.jit.rainbow.test.test_interpreter import P_NOVIRTUAL
+from pypy.jit.rainbow.test.test_vlist import P_OOPSPEC
+from pypy.rlib.jit import hint
+from pypy.rpython.module.support import LLSupport
+
+class TestPromotion(InterpretationTest):
+    type_system = "lltype"
+    small = True
+
+    def test_simple_promotion(self):
+        def ll_two(k):
+            return (k+1)*2
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            k = hint(n, promote=True)
+            k = ll_two(k)
+            return hint(k, variable=True)
+
+        # easy case: no promotion needed
+        res = self.interpret(ll_function, [20], [0])
+        assert res == 42
+        self.check_insns({})
+
+        # the real test: with promotion
+        res = self.interpret(ll_function, [20], [])
+        assert res == 42
+        self.check_insns(int_add=0, int_mul=0)
+
+    def test_many_promotions(self):
+        def ll_two(k):
+            return k*k
+        def ll_function(n, total):
+            while n > 0:
+                hint(None, global_merge_point=True)
+                k = hint(n, promote=True)
+                k = ll_two(k)
+                total += hint(k, variable=True)
+                n -= 1
+            return total
+
+        res = self.interpret(ll_function, [10, 0], [], policy=P_NOVIRTUAL)
+        assert res == ll_function(10, 0)
+        self.check_insns(int_add=10, int_mul=0)
+
+    def test_promote_after_call(self):
+        S = lltype.GcStruct('S', ('x', lltype.Signed))
+        def ll_two(k, s):
+            if k > 5:
+                s.x = 20
+            else:
+                s.x = 10
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            s = lltype.malloc(S)
+            ll_two(n, s)
+            k = hint(n, promote=True)
+            k *= 17
+            return hint(k, variable=True) + s.x
+
+        res = self.interpret(ll_function, [4], [], policy=P_NOVIRTUAL)
+        assert res == 4*17 + 10
+        self.check_insns(int_mul=0, int_add=1)
+
+    def test_promote_after_yellow_call(self):
+        S = lltype.GcStruct('S', ('x', lltype.Signed))
+        def ll_two(k, s):
+            if k > 5:
+                s.x = 20*k
+                return 7
+            else:
+                s.x = 10*k
+                return 9
+            
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            s = lltype.malloc(S)
+            c = ll_two(n, s)
+            k = hint(s.x, promote=True)
+            k += c
+            return hint(k, variable=True)
+
+        res = self.interpret(ll_function, [4], [], policy=P_NOVIRTUAL)
+        assert res == 49
+        self.check_insns(int_add=0)
+
+    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):
+            hint(None, global_merge_point=True)
+            return ll_two(n + 1) - 1
+
+        res = self.interpret(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):
+            hint(None, global_merge_point=True)
+            n1 = hint(n, promote=True)
+            m1 = hint(m, promote=True)
+            s1 = n1 + m1
+            return hint(s1, variable=True)
+
+        res = self.interpret(ll_function, [40, 2], [], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_insns(int_add=0)
+
+    def test_merge_then_promote(self):
+        S = lltype.GcStruct('S', ('x', lltype.Signed))
+        def ll_two(n):
+            s = lltype.malloc(S)
+            if n < 0:
+                s.x = 10
+            else:
+                s.x = 20
+            k = hint(s.x, promote=True)
+            k *= 17
+            return hint(k, variable=True)
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            return ll_two(n)
+
+        res = self.interpret(ll_function, [3], [], policy=P_NOVIRTUAL)
+        assert res == 340
+        self.check_insns(int_lt=1, int_mul=0)
+
+    def test_vstruct_unfreeze(self):
+        S = lltype.GcStruct('S', ('x', lltype.Signed))
+        def ll_two(k):
+            return (k+1)*2
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            s = lltype.malloc(S)
+            s.x = n
+            k = hint(n, promote=True)
+            k = ll_two(k)
+            return hint(k, variable=True) + s.x
+
+        # easy case: no promotion needed
+        res = self.interpret(ll_function, [20], [0], policy=P_NOVIRTUAL)
+        assert res == 62
+        self.check_insns({})
+
+        # the real test: with promotion
+        res = self.interpret(ll_function, [20], [], policy=P_NOVIRTUAL)
+        assert res == 62
+        self.check_insns(int_add=0, int_mul=0)
+
+    def test_more_promotes(self):
+        py.test.skip("not working yet")
+        S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed))
+        def ll_two(s, i, m):
+            if i > 4:
+                s.x += i
+                return 10
+            else:
+                s.y = i
+                return s.x + m
+        def ll_three(s, k):
+            k = hint(k, promote=True)
+            if s.x > 6:
+                k *= hint(s.y, promote=True)
+                return k
+            else:
+                return hint(1, concrete=True)
+        def ll_function(n, m):
+            s = lltype.malloc(S)
+            s.x = 0
+            s.y = 0
+            i = 0
+            while i < n:
+                hint(None, global_merge_point=True)
+                k = ll_two(s, i, m)
+                if m & 1:
+                    k *= 3
+                else:
+                    s.y += 1
+                j = ll_three(s, k)
+                j = hint(j, variable=True)
+                i += j
+            return s.x + s.y * 17
+
+        res = self.interpret(ll_function, [100, 2], [], policy=P_NOVIRTUAL)
+        assert res == ll_function(100, 2)
+
+    def test_mixed_merges(self):
+        def ll_function(x, y, z, k):
+            if x:
+               while x > 0:
+                   hint(None, global_merge_point=True)
+                   if y < 0:
+                       y = -y
+                       hint(None, reverse_split_queue=True)
+                       return y
+                   else:
+                       n = 10
+                       while n:
+                           n -= 1
+                       y = hint(y, promote=True)
+                       y *= 2
+                       y = hint(y, variable=True)
+                   x -= 1
+            else:
+                if z < 0:
+                    z = -z
+                else:
+                    k = 3
+                y = y + z*k
+            return y
+
+        res = self.interpret(ll_function, [6, 3, 2, 2], [3], policy=P_NOVIRTUAL)
+
+        assert res == ll_function(6, 3, 2, 2)
+
+    def test_green_across_global_mp(self):
+        py.test.skip("void vars not handled correctly")
+        def ll_function(n1, n2, n3, n4, total):
+            while n2:
+                hint(None, global_merge_point=True)
+                total += n3
+                hint(n4, concrete=True)
+                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]
+
+        res = self.interpret(ll_function, [None, 4, 3, None, 100], [0],
+                             policy=P_NOVIRTUAL)
+        assert res == ll_function(None, 4, 3, None, 100)
+
+    def test_remembers_across_mp(self):
+        def ll_function(x, flag):
+            hint(None, global_merge_point=True)
+            hint(x.field, promote=True)
+            m = x.field
+            if flag:
+                m += 1 * flag
+            else:
+                m += 2 + flag
+            hint(x.field, promote=True)
+            return m + x.field
+
+        S = lltype.GcStruct('S', ('field', lltype.Signed),
+                            hints={'immutable': True})
+
+        def struct_S(string):
+            s = lltype.malloc(S)
+            s.field = int(string)
+            return s
+        ll_function.convert_arguments = [struct_S, int]
+
+        res = self.interpret(ll_function, ["20", 0], [], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_flexswitches(1)
+
+    def test_virtual_list_copy(self):
+        def ll_function(x, y):
+            hint(None, global_merge_point=True)
+            l = [y] * x
+            size = len(l)
+            size = hint(size, promote=True)
+            vl = [0] * size
+            i = 0
+            while i < size:
+                hint(i, concrete=True)
+                vl[i] = l[i]
+                i = i + 1
+            return len(vl)
+        res = self.interpret(ll_function, [6, 5], [], policy=P_OOPSPEC)
+        assert res == 6
+        self.check_oops(**{'newlist': 1, 'list.len': 1})
+            
+    def test_promote_bug_1(self):
+        def ll_function(x, y, z):
+            a = 17
+            while True:
+                hint(None, global_merge_point=True)
+                y += 1
+
+                if a != 17:
+                    z = -z
+                
+                if z > 0:
+                    b = 1 - z
+                else:
+                    b = 2
+                y = -y
+                if b == 2:
+                    hint(z, promote=True)
+                    return y + z + a
+                a += z
+
+        assert ll_function(1, 5, 8) == 22
+        res = self.interpret(ll_function, [1, 5, 8], [],
+                             policy=P_NOVIRTUAL)
+        assert res == 22
+
+    def test_raise_result_mixup(self):
+        py.test.skip("residual calls not supported")
+        def w(x):
+            pass
+        class E(Exception):
+            def __init__(self, x):
+                self.x = x
+        def o(x):
+            if x < 0:
+                e = E(x)
+                w(e)
+                raise e                
+            return x
+        def ll_function(c, x):
+            i = 0
+            while True:
+                hint(None, global_merge_point=True)
+                op = c[i]
+                hint(op, concrete=True)
+                if op == 'e':
+                    break
+                elif op == 'o':
+                    x = o(x)
+                    x = hint(x, promote=True)
+                    i = x
+            r = hint(i, variable=True)
+            return r
+        ll_function.convert_arguments = [LLSupport.to_rstr, int]
+        
+        assert ll_function("oe", 1) == 1
+
+        res = self.interpret(ll_function, ["oe", 1], [],
+                             policy=StopAtXPolicy(w))
+        res == 1
+
+    def test_raise_result_mixup_some_more(self):
+        py.test.skip("residual calls not supported")
+        def w(x):
+            if x > 1000:
+                return None
+            else:
+                return E(x)
+        class E(Exception):
+            def __init__(self, x):
+                self.x = x
+        def o(x):
+            if x < 0:
+                e = w(x)
+                raise e                
+            return x
+        def ll_function(c, x):
+            i = 0
+            while True:
+                hint(None, global_merge_point=True)
+                op = c[i]
+                hint(op, concrete=True)
+                if op == 'e':
+                    break
+                elif op == 'o':
+                    x = o(x)
+                    x = hint(x, promote=True)
+                    i = x
+            r = hint(i, variable=True)
+            return r
+        ll_function.convert_arguments = [LLSupport.to_rstr, int]
+        
+        assert ll_function("oe", 1) == 1
+
+        res = self.interpret(ll_function, ["oe", 1], [],
+                             policy=StopAtXPolicy(w))
+        res == 1
+
+    def test_promote_in_yellow_call(self):
+        def ll_two(n):
+            n = hint(n, promote=True)
+            return n + 2
+            
+        def ll_function(n):
+            hint(None, global_merge_point=True)
+            c = ll_two(n)
+            return hint(c, variable=True)
+
+        res = self.interpret(ll_function, [4], [], policy=P_NOVIRTUAL)
+        assert res == 6
+        self.check_insns(int_add=0)
+
+    def test_two_promotions_in_call(self):
+        def ll_two(n, m):
+            if n < 1:
+                return m
+            else:
+                return n
+
+        def ll_one(n, m):
+            n = ll_two(n, m)
+            n = hint(n, promote=True)
+            m = hint(m, promote=True)
+            return hint(n + m, variable=True)
+
+        def ll_function(n, m):
+            hint(None, global_merge_point=True)
+            c = ll_one(n, m)
+            return c
+
+        res = self.interpret(ll_function, [4, 7], [], policy=P_NOVIRTUAL)
+        assert res == 11
+        self.check_insns(int_add=0)



More information about the Pypy-commit mailing list