[pypy-svn] r35775 - in pypy/dist/pypy/translator/cli: . test

antocuni at codespeak.net antocuni at codespeak.net
Fri Dec 15 10:32:54 CET 2006


Author: antocuni
Date: Fri Dec 15 10:32:54 2006
New Revision: 35775

Modified:
   pypy/dist/pypy/translator/cli/function.py
   pypy/dist/pypy/translator/cli/test/test_backendopt.py
Log:
Use the naive version of numeri_switch when one or more cases are
negative.



Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py	(original)
+++ pypy/dist/pypy/translator/cli/function.py	Fri Dec 15 10:32:54 2006
@@ -7,6 +7,7 @@
 from pypy.rpython.lltypesystem.lltype import Void
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.oosupport.function import Function as OOFunction
+from pypy.translator.oosupport.constant import push_constant
 from pypy.translator.cli.option import getoption
 from pypy.translator.cli.cts import CTS
 from pypy.translator.cli.opcodes import opcodes
@@ -16,7 +17,7 @@
 from pypy.translator.cli.support import log
 from pypy.translator.cli.ilgenerator import CLIBaseGenerator
 
-USE_LAST = False
+USE_LAST = True
 
 class NativeExceptionHandler(object):
     def begin_try(self):
@@ -206,6 +207,7 @@
 
     def render_numeric_switch(self, block):
         cases = {}
+        naive = False
         for link in block.exits:
             if link.exitcase == "default":
                 default = link, self.next_label('switch')
@@ -214,12 +216,21 @@
                     value = ord(link.exitcase)
                 else:
                     value = link.exitcase
-                assert value >= 0
+                if value < 0:
+                    naive = True
+                    break
                 cases[value] = link, self.next_label('switch')
 
-        max_case = max(cases.keys())
+        try:
+            max_case = max(cases.keys())
+        except ValueError:
+            max_case = 0
         if max_case > 4096: # XXX: how to find a good way to determine whether to use switch?
-            raise NotImplementedError # TODO
+            naive = True
+
+        if naive:
+            self.render_numeric_switch_naive(block)
+            return
 
         targets = []
         for i in xrange(max_case+1):
@@ -237,6 +248,17 @@
         self._setup_link(link)
         self.generator.branch_unconditionally(target_label)
 
+    def render_numeric_switch_naive(self, block):
+        for link in block.exits:
+            target_label = self._get_block_name(link.target)
+            self._setup_link(link)
+            if link.exitcase == 'default':
+                self.ilasm.opcode('br', target_label)
+            else:
+                push_constant(self.db, block.exitswitch.concretetype, link.exitcase, self)
+                self.generator.load(block.exitswitch)
+                self.ilasm.opcode('beq', target_label)
+
     # Those parts of the generator interface that are function
     # specific
 

Modified: pypy/dist/pypy/translator/cli/test/test_backendopt.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_backendopt.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_backendopt.py	Fri Dec 15 10:32:54 2006
@@ -20,3 +20,17 @@
 
     def test_ulonglong_switch(self):
         py.test.skip('Not yet supported')
+
+    def test_switch_naive(self):
+        def fn(x):
+            if x == -1:
+                return 3
+            elif x == 3:
+                return 9
+            elif x == 9:
+                return -1
+            return 42
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(fn, [int])
+        for x in (-5,-1,0,3,9,27,48):
+            assert fn(x) == fn(x)


More information about the pypy-svn mailing list