[pypy-svn] r15701 - in pypy/dist/pypy/translator/llvm2: . module test
ericvrp at codespeak.net
ericvrp at codespeak.net
Fri Aug 5 17:51:31 CEST 2005
Author: ericvrp
Date: Fri Aug 5 17:51:30 2005
New Revision: 15701
Modified:
pypy/dist/pypy/translator/llvm2/funcnode.py
pypy/dist/pypy/translator/llvm2/genllvm.py
pypy/dist/pypy/translator/llvm2/module/support.py
pypy/dist/pypy/translator/llvm2/opwriter.py
pypy/dist/pypy/translator/llvm2/test/test_exception.py
pypy/dist/pypy/translator/llvm2/test/test_typed.py
Log:
- fixed bug that only direct_calls could raise exceptions, operations can now also
- added int_floordiv_zer and uint_floordiv_zer
- cleaned up similar attempt in genllvm.py
Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py Fri Aug 5 17:51:30 2005
@@ -156,30 +156,28 @@
codewriter.br(cond, self.block_to_name[block.exits[0].target],
self.block_to_name[block.exits[1].target])
- def _last_operation(self, block, opname):
- last_index = None
- for op_index, op in enumerate(block.operations):
- if op.opname == opname:
- last_index = op_index
- return last_index
-
def write_block_operations(self, codewriter, block):
opwriter = OpWriter(self.db, codewriter, self, block)
- last_direct_call_index = self._last_operation(block, 'direct_call')
+ if block.exitswitch == Constant(last_exception):
+ last_op_index = len(block.operations) - 1
+ else:
+ last_op_index = None
for op_index, op in enumerate(block.operations):
-
- # print out debug string
- codewriter.newline()
- codewriter.comment("** %s **" % str(op))
- info = self.db.get_op2comment(op)
- if info is not None:
- lenofopstr, opstrname = info
- codewriter.debugcomment(self.db.repr_tmpvar(),
- lenofopstr,
- opstrname)
-
- if op_index == last_direct_call_index and block.exitswitch == Constant(last_exception):
- op.opname = 'direct_invoke'
+ if False: # print out debug string
+ codewriter.newline()
+ codewriter.comment("** %s **" % str(op))
+ info = self.db.get_op2comment(op)
+ if info is not None:
+ lenofopstr, opstrname = info
+ codewriter.debugcomment(self.db.repr_tmpvar(),
+ lenofopstr,
+ opstrname)
+ if op_index == last_op_index:
+ #could raise an exception and should therefor have a function
+ #implementation that can be invoked by the llvm-code.
+ invoke_prefix = 'invoke:'
+ assert not op.opname.startswith(invoke_prefix)
+ op.opname = invoke_prefix + op.opname
opwriter.write_operation(op)
def write_startblock(self, codewriter, block):
Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 5 17:51:30 2005
@@ -20,18 +20,6 @@
function_count = {}
-# XXX Temp
-raise_impl = """
-ccc void %RaiseSimpleException(int %t, sbyte* %ptErr) {
-entry:
- unwind
- ret void
-}
-"""
-
-# XXX Temp
-raise_decl = "declare ccc void %RaiseSimpleException(int, sbyte*)"
-
class GenLLVM(object):
def __init__(self, translator, debug=False, embedexterns=True):
@@ -89,7 +77,6 @@
nl(); comment("Function Prototypes") ; nl()
if self.embedexterns:
- codewriter.append(raise_decl)
for extdecl in extdeclarations.split('\n'):
codewriter.append(extdecl)
@@ -125,9 +112,6 @@
codewriter.append(extfunc)
depdone[dep] = True
- if self.embedexterns:
- codewriter.append(raise_impl)
-
#XXX use codewriter methods here
decl = self.entrynode.getdecl()
t = decl.split('%', 1)
Modified: pypy/dist/pypy/translator/llvm2/module/support.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/module/support.py (original)
+++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 5 17:51:30 2005
@@ -23,3 +23,54 @@
}
""")
+
+extfunctions["%__prepare_ZeroDivisionError"] = ((), """
+fastcc void %__prepare_ZeroDivisionError() {
+
+ %exception_value = call fastcc %structtype.object* %instantiate_ZeroDivisionError()
+
+ %tmp = getelementptr %structtype.object* %exception_value, int 0, uint 0
+ %exception_type = load %structtype.object_vtable** %tmp
+ store %structtype.object_vtable* %exception_type, %structtype.object_vtable** %last_exception_type
+ store %structtype.object* %exception_value, %structtype.object** %last_exception_value
+
+ ret void
+}
+
+""")
+
+extfunctions["%int_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """
+fastcc int %int_floordiv_zer(int %x, int %y) {
+ %cond = seteq int %y, 0
+ br bool %cond, label %is_0, label %is_not_0
+is_not_0:
+ %z = add int %x, %y
+ ret int %z
+is_0:
+ call fastcc void %__prepare_ZeroDivisionError()
+ unwind
+}
+
+""")
+
+#XXX could use template here
+extfunctions["%uint_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """
+fastcc uint %uint_floordiv_zer(uint %x, uint %y) {
+ %cond = seteq uint %y, 0
+ br bool %cond, label %is_0, label %is_not_0
+is_not_0:
+ %z = add uint %x, %y
+ ret uint %z
+is_0:
+ call fastcc void %__prepare_ZeroDivisionError()
+ unwind
+}
+
+""")
+
+#src/int.h:#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ done
+#src/int.h:#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ done
+#src/int.h:#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \
+#src/int.h:#define OP_INT_MOD_ZER(x,y,r,err) \
+#src/int.h:#define OP_UINT_MOD_ZER(x,y,r,err) \
+#src/int.h:#define OP_INT_MOD_OVF_ZER(x,y,r,err)
Modified: pypy/dist/pypy/translator/llvm2/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/opwriter.py (original)
+++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 5 17:51:30 2005
@@ -1,6 +1,8 @@
import py
from pypy.objspace.flow.model import Constant
from pypy.rpython import lltype
+from pypy.translator.llvm2.module.extfunction import extfunctions
+from pypy.translator.llvm2.extfuncnode import ExternalFuncNode
from pypy.translator.llvm2.log import log
log = log.opwriter
@@ -79,14 +81,18 @@
self.block = block
def write_operation(self, op):
- if op.opname in self.binary_operations:
- self.binaryop(op)
- elif op.opname in self.shift_operations:
- self.shiftop(op)
+ invoke = op.opname.startswith('invoke:')
+ if invoke:
+ self.invoke(op)
else:
- meth = getattr(self, op.opname, None)
- assert meth is not None, "operation %r not found" %(op.opname,)
- meth(op)
+ if op.opname in self.binary_operations:
+ self.binaryop(op)
+ elif op.opname in self.shift_operations:
+ self.shiftop(op)
+ else:
+ meth = getattr(self, op.opname, None)
+ assert meth is not None, "operation %s not found" %(op.opname,)
+ meth(op)
def _generic_pow(self, op, onestr):
mult_type = self.db.repr_arg_type(op.args[0])
@@ -228,11 +234,21 @@
else:
self.codewriter.call_void(functionref, argrefs, argtypes)
- def direct_invoke(self, op):
+ def invoke(self, op):
# XXX hack as per remove_voids()
op_args = [arg for arg in op.args
if arg.concretetype is not lltype.Void]
+ if op.opname == 'invoke:direct_call':
+ functionref = self.db.repr_arg(op_args[0])
+ else: #operation
+ opname = op.opname.split(':',1)[1]
+ op_args = ['%' + opname] + op_args
+ functionref = op_args[0]
+ ExternalFuncNode.used_external_functions[functionref] = True
+ assert functionref in extfunctions, \
+ "exception raising operation %(opname)s has no implementation" % locals()
+
assert len(op_args) >= 1
assert len(self.block.exits) >= 2 #at least one label and one exception label
@@ -241,7 +257,6 @@
targetvar = self.db.repr_arg(op.result)
returntype = self.db.repr_arg_type(op.result)
- functionref = self.db.repr_arg(op_args[0])
argrefs = self.db.repr_arg_multi(op_args[1:])
argtypes = self.db.repr_arg_type_multi(op_args[1:])
Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original)
+++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Fri Aug 5 17:51:30 2005
@@ -2,6 +2,7 @@
from pypy.translator.llvm2.genllvm import compile_function
from pypy.translator.test.snippet import try_raise_choose
+from pypy.rpython.rarithmetic import r_uint
class TestException(Exception):
pass
@@ -91,17 +92,28 @@
assert f( 0) == fn( 0)
assert f(10) == fn(10)
-#def test_divzero():
-# py.test.skip("divzero not working yet")
-# def fn(n):
-# try:
-# n/0
-# except:
-# return 2
-# return 4
-# f = compile_function(fn, [int])
-# assert f(0) == fn(0)
-
+def test_zerodiv_int():
+ def zerodiv_int(n):
+ try:
+ 100/n
+ except ZeroDivisionError:
+ return n+7
+ return n+4
+ f = compile_function(zerodiv_int, [int])
+ assert f(1) == zerodiv_int(1)
+ assert f(0) == zerodiv_int(0)
+
+def test_zerodiv_uint():
+ def zerodiv_uint(n):
+ try:
+ 100/n
+ except ZeroDivisionError:
+ return n+7
+ return n+4
+ f = compile_function(zerodiv_uint, [r_uint])
+ assert f(1) == zerodiv_uint(1)
+ assert f(0) == zerodiv_uint(0)
+
def test_reraise1():
def fn(n):
lst = range(10)
Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original)
+++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Fri Aug 5 17:51:30 2005
@@ -211,7 +211,7 @@
# floats
def test_float_operations():
- py.test.skip("llvm rem operation doesnt seem to work...fixed in llvm cvs")
+ #llvm rem operation working starting llvm1.6")
#see: http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=611
def func(x, y):
z = x + y / 2.1 * x
More information about the Pypy-commit
mailing list