[pypy-svn] r21314 - in pypy/dist/pypy/translator: backendopt backendopt/test c c/test

ac at codespeak.net ac at codespeak.net
Mon Dec 19 15:34:13 CET 2005


Author: ac
Date: Mon Dec 19 15:34:13 2005
New Revision: 21314

Modified:
   pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
   pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
   pypy/dist/pypy/translator/c/funcgen.py
   pypy/dist/pypy/translator/c/test/test_backendoptimized.py
Log:
Extend the 'if ... elif ...' merging to other types than
Signed.



Modified: pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/merge_if_blocks.py	(original)
+++ pypy/dist/pypy/translator/backendopt/merge_if_blocks.py	Mon Dec 19 15:34:13 2005
@@ -10,7 +10,9 @@
     if len(block.operations) > 1 and not first:
         return False
     op = block.operations[-1]
-    if op.opname != 'int_eq' or op.result != block.exitswitch:
+    if (op.opname not in ('int_eq', 'uint_eq', 'llong_eq', 'ullong_eq',
+                          'char_eq', 'unichar_eq')
+        or op.result != block.exitswitch):
         return False
     if isinstance(op.args[0], Variable) and isinstance(op.args[1], Variable):
         return False

Modified: pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py	Mon Dec 19 15:34:13 2005
@@ -5,33 +5,64 @@
 from pypy.objspace.flow.model import flatten, Block
 from pypy.translator.backendopt.removenoops import remove_same_as
 from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.rarithmetic import r_uint, r_ulonglong, r_longlong
+from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint
 
-def test_merge1():
-    def merge1(n):
-        n += 1
-        if n == 1:
-            return 1
-        elif n == 2:
-            return 2
-        elif n == 3:
-            return 3
-        return 4
+def do_test_merge(fn, testvalues):
     t = TranslationContext()
     a = t.buildannotator()
-    a.build_types(merge1, [int])
+    a.build_types(fn, [type(testvalues[0])])
     rtyper = t.buildrtyper()
     rtyper.specialize()
-    graph = tgraphof(t, merge1)
+    graph = tgraphof(t, fn)
     assert len(list(graph.iterblocks())) == 4 #startblock, blocks, returnblock
     remove_same_as(graph)
     merge_if_blocks_once(graph)
     assert len(graph.startblock.exits) == 4
     assert len(list(graph.iterblocks())) == 2 #startblock, returnblock
     interp = LLInterpreter(rtyper)
-    for i in range(4):
-        res = interp.eval_graph(graph, [i])
-        assert res == i + 1
+    for i in testvalues:
+        expected = fn(i)
+        actual = interp.eval_graph(graph, [i])
+        assert actual == expected
 
+def test_merge1():
+    def merge_int(n):
+        n += 1
+        if n == 1:
+            return 1
+        elif n == 2:
+            return 2
+        elif n == 3:
+            return 3
+        return 4
+    do_test_merge(merge_int, range(4))
+    do_test_merge(merge_int, [r_uint(i) for i in range(4)])
+    do_test_merge(merge_int, [r_longlong(i) for i in range(4)])
+    do_test_merge(merge_int, [r_ulonglong(i) for i in range(4)])
+
+    def merge_chr(n):
+        c = chr(n + 1)
+        if c == 'a':
+            return 'a'
+        elif c == 'b':
+            return 'b'
+        elif c == 'c':
+            return 'c'
+        return 'd'
+    do_test_merge(merge_chr, range(96, 101))
+
+    def merge_uchr(n):
+        c = unichr(n + 1)
+        if c == u'a':
+            return u'a'
+        elif c == u'b':
+            return u'b'
+        elif c == u'c':
+            return u'c'
+        return u'd'
+    do_test_merge(merge_uchr, range(96, 101))
+    
 def test_merge_passonvars():
     def merge(n, m):
         if n == 1:

Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/dist/pypy/translator/c/funcgen.py	Mon Dec 19 15:34:13 2005
@@ -5,7 +5,7 @@
 from pypy.objspace.flow.model import Variable, Constant, Block
 from pypy.objspace.flow.model import traverse, c_last_exception
 from pypy.rpython.lltypesystem.lltype import \
-     Ptr, PyObject, Void, Bool, Signed, pyobjectptr, Struct, Array
+     Ptr, PyObject, Void, Bool, Signed, Unsigned, SignedLongLong, UnsignedLongLong,Char, UniChar, pyobjectptr, Struct, Array
 
 
 PyObjPtr = Ptr(PyObject)
@@ -345,7 +345,8 @@
                     for op in gen_link(block.exits[-1]):
                         yield op
                     yield ''
-                elif TYPE == Signed:
+                elif TYPE in (Signed, Unsigned, SignedLongLong,
+                              UnsignedLongLong, Char, UniChar):
                     defaultlink = None
                     expr = self.expr(block.exitswitch)
                     yield 'switch (%s) {' % self.expr(block.exitswitch)
@@ -353,7 +354,7 @@
                         if link.exitcase is 'default':
                             defaultlink = link
                             continue
-                        yield 'case %s:' % link.llexitcase
+                        yield 'case %s:' % self.db.get(link.llexitcase)
                         for op in gen_link(link):
                             yield '\t' + op
                         yield 'break;'

Modified: pypy/dist/pypy/translator/c/test/test_backendoptimized.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_backendoptimized.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_backendoptimized.py	Mon Dec 19 15:34:13 2005
@@ -2,7 +2,7 @@
 from pypy.translator.c.test.test_typed import TestTypedTestCase as _TestTypedTestCase
 from pypy.translator.backendopt.all import backend_optimizations
 from pypy.rpython import objectmodel
-
+from pypy.rpython.rarithmetic import r_uint, r_longlong, r_ulonglong
 
 class TestTypedOptimizedTestCase(_TestTypedTestCase):
 
@@ -105,7 +105,7 @@
             self.t = t
             backend_optimizations(t, merge_if_blocks_to_switch=True)
 
-    def test_switch(self):
+    def test_int_switch(self):
         def f(x=int):
             if x == 3:
                 return 9
@@ -119,3 +119,77 @@
         for x in (0,1,2,3,9,27,48, -9):
             assert fn(x) == f(x)
 
+    def test_uint_switch(self):
+        def f(x=r_uint):
+            if x == r_uint(3):
+                return 9
+            elif x == r_uint(9):
+                return 27
+            elif x == r_uint(27):
+                return 3
+            return 0
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in (0,1,2,3,9,27,48):
+            assert fn(x) == f(x)
+
+    def test_longlong_switch(self):
+        def f(x=r_longlong):
+            if x == r_longlong(3):
+                return 9
+            elif x == r_longlong(9):
+                return 27
+            elif x == r_longlong(27):
+                return 3
+            return 0
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in (0,1,2,3,9,27,48, -9):
+            assert fn(x) == f(x)
+
+    def test_ulonglong_switch(self):
+        def f(x=r_ulonglong):
+            if x == r_ulonglong(3):
+                return 9
+            elif x == r_ulonglong(9):
+                return 27
+            elif x == r_ulonglong(27):
+                return 3
+            return 0
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in (0,1,2,3,9,27,48, -9):
+            assert fn(x) == f(x)
+
+    def test_chr_switch(self):
+        def f(y=int):
+            x = chr(y)
+            if x == 'a':
+                return 'b'
+            elif x == 'b':
+                return 'c'
+            elif x == 'c':
+                return 'd'
+            return '@'
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in 'ABCabc@':
+            y = ord(x)
+            assert fn(y) == f(y)
+
+    def test_unichr_switch(self):
+        def f(y=int):
+            x = unichr(y)
+            if x == u'a':
+                return 'b'
+            elif x == u'b':
+                return 'c'
+            elif x == u'c':
+                return 'd'
+            return '@'
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in u'ABCabc@':
+            y = ord(x)
+            assert fn(y) == f(y)
+



More information about the Pypy-commit mailing list