[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