[pypy-svn] r35635 - in pypy/dist/pypy/translator/llvm: . test

mwh at codespeak.net mwh at codespeak.net
Tue Dec 12 16:47:33 CET 2006


Author: mwh
Date: Tue Dec 12 16:47:31 2006
New Revision: 35635

Modified:
   pypy/dist/pypy/translator/llvm/funcnode.py
   pypy/dist/pypy/translator/llvm/test/test_genllvm.py
Log:
support for switches without defaults in genllvm.


Modified: pypy/dist/pypy/translator/llvm/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/funcnode.py	Tue Dec 12 16:47:31 2006
@@ -33,13 +33,14 @@
 
 
 class FuncNode(ConstantLLVMNode):
-    __slots__ = "db value ref graph block_to_name".split()
+    __slots__ = "db value ref graph block_to_name bad_switch_block".split()
 
     def __init__(self, db, value):
         self.db = db
         self.value = value
         self.ref   = self.make_ref('%pypy_', value.graph.name)
         self.graph = value.graph
+        self.bad_switch_block = False
 
         #XXX experimental
         #from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs
@@ -90,6 +91,14 @@
                     break
             else:
                 self.write_block(codewriter, block)
+        if self.bad_switch_block:
+            codewriter.label('badswitch')
+            codewriter._indent('call void %abort()')
+            rettype = self.graph.getreturnvar().concretetype
+            if rettype is lltype.Void:
+                codewriter._indent('ret')
+            else:
+                codewriter._indent('ret %s 0'%(self.db.repr_type(rettype)))
         codewriter.closefunc()
 
     def writeglobalconstants(self, codewriter):
@@ -177,8 +186,13 @@
                 value_labels.append( (exitcase,
                                       self.block_to_name[link.target]) )
 
-            codewriter.switch(condtype, cond,
-                              self.block_to_name[defaultlink.target], value_labels)
+            if defaultlink:
+                defaultblockname = self.block_to_name[defaultlink.target]
+            else:
+                defaultblockname = 'badswitch'
+                self.bad_switch_block = True
+
+            codewriter.switch(condtype, cond, defaultblockname, value_labels)
 
         else:
             raise BranchException("exitswitch type '%s' not supported" %

Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py	Tue Dec 12 16:47:31 2006
@@ -441,3 +441,21 @@
     assert f(0) == 0
     
 
+def test_switch_no_default():
+    from pypy.objspace.flow.model import FunctionGraph, Block, Constant, Link
+    from pypy.rpython.lltypesystem.lltype import FuncType, Signed, functionptr
+    from pypy.translator.unsimplify import varoftype
+    block = Block([varoftype(Signed)])
+    block.exitswitch = block.inputargs[0]
+    graph = FunctionGraph("t", block, varoftype(Signed))
+    links = []
+    for i in range(10):
+        links.append(Link([Constant(i*i, Signed)], graph.returnblock, i))
+        links[-1].llexitcase = i
+    block.closeblock(*links)
+    fptr = functionptr(FuncType([Signed], Signed), "t", graph=graph)
+    def func(x):
+        return fptr(x)
+    f = compile_function(func, [int])
+    res = f(4)
+    assert res == 16



More information about the Pypy-commit mailing list