[pypy-svn] r15748 - in pypy/dist/pypy/translator/llvm2: . module test
ericvrp at codespeak.net
ericvrp at codespeak.net
Sun Aug 7 18:23:25 CEST 2005
Author: ericvrp
Date: Sun Aug 7 18:23:24 2005
New Revision: 15748
Modified:
pypy/dist/pypy/translator/llvm2/codewriter.py
pypy/dist/pypy/translator/llvm2/genllvm.py
pypy/dist/pypy/translator/llvm2/module/support.py
pypy/dist/pypy/translator/llvm2/test/test_exception.py
Log:
- Added int_neg_ovf and int_abs_ovf
(need to look into why supplied tests not generating these operands)
- Refactored codewriter and genllvm to directly generate a llvm-sourcefile
(was using an in-memory copy that just takes up valuable memory)
Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py (original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py Sun Aug 7 18:23:24 2005
@@ -3,17 +3,19 @@
from pypy.translator.llvm2.log import log
log = log.codewriter
-show_line_numbers = False # True
-count = count().next
class CodeWriter(object):
- def __init__(self):
- self._lines = []
+ def __init__(self, f, show_line_number=False):
+ self.f = f
+ self.show_line_numbers = show_line_number
+ self.n_lines = 0
+ self.count = count().next
def append(self, line):
- if show_line_numbers:
- line = "%-75s; %d" % (line, len(self._lines) + 1)
- self._lines.append(line)
+ self.n_lines += 1
+ if self.show_line_numbers:
+ line = "%-75s; %d" % (line, self.n_lines)
+ print >> self.f, line
def comment(self, line, indent=True):
line = ";; " + line
@@ -120,7 +122,7 @@
"%(fromvar)s to %(targettype)s" % locals())
def malloc(self, targetvar, type_, size=1, atomic=False):
- cnt = count()
+ cnt = self.count()
postfix = ('', '_atomic')[atomic]
self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, uint %(size)s" % locals())
self.indent("%%malloc.SizeU.%(cnt)d = cast %(type_)s* %%malloc.Size.%(cnt)d to uint" % locals())
@@ -145,5 +147,5 @@
res = res % (tmpname, len, tmpname)
self.indent(res)
- def __str__(self):
- return "\n".join(self._lines)
+ #def __str__(self):
+ # return "\n".join(self._lines)
Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py Sun Aug 7 18:23:24 2005
@@ -36,7 +36,7 @@
# for debug we create comments of every operation that may be executed
self.debug = debug
- def compile(self, func=None):
+ def gen_llvm_source(self, func=None):
if func is None:
func = self.translator.entrypoint
self.entrypoint = func
@@ -55,10 +55,21 @@
assert c in self.db.obj2node
self.db.setup_all()
- log.compile(self.db.dump_pbcs())
+ if self.debug:
+ log.gen_llvm_source(self.db.dump_pbcs())
self.entrynode = self.db.obj2node[c]
- codewriter = CodeWriter()
+
+ # prevent running the same function twice in a test
+ if func.func_name in function_count:
+ postfix = '_%d' % function_count[func.func_name]
+ function_count[func.func_name] += 1
+ else:
+ postfix = ''
+ function_count[func.func_name] = 1
+ filename = udir.join(func.func_name + postfix).new(ext='.ll')
+
+ codewriter = CodeWriter( open(str(filename),'w') )
comment = codewriter.comment
nl = codewriter.newline
@@ -141,39 +152,26 @@
codewriter.newline()
comment("End of file") ; nl()
- self.content = str(codewriter)
- return self.content
-
- def create_module(self, exe_name=None):
- # hack to prevent running the same function twice in a test
- func = self.entrypoint
- if func.func_name in function_count:
- postfix = '_%d' % function_count[func.func_name]
- function_count[func.func_name] += 1
- else:
- postfix = ''
-
- function_count[func.func_name] = 1
-
- targetdir = udir
- llvmsource = targetdir.join(func.func_name+postfix).new(ext='.ll')
- llvmsource.write(self.content) # XXX writing to disc directly would conserve memory
+ return filename
+ def create_module(self, filename, exe_name=None):
if not llvm_is_on_path():
py.test.skip("llvm not found") # XXX not good to call py.test.skip here
- pyxsource = llvmsource.new(basename=llvmsource.purebasename+'_wrapper'+postfix+'.pyx')
+ postfix = ''
+ pyxsource = filename.new(basename=filename.purebasename+'_wrapper'+postfix+'.pyx')
write_pyx_wrapper(self.entrynode, pyxsource)
- return build_llvm_module.make_module_from_llvm(llvmsource, pyxsource, exe_name=exe_name)
+ return build_llvm_module.make_module_from_llvm(filename, pyxsource, exe_name=exe_name)
def _debug_prototype(self, codewriter):
codewriter.append("declare int %printf(sbyte*, ...)")
def genllvm(translator, embedexterns=True, exe_name=None):
gen = GenLLVM(translator, embedexterns=embedexterns)
- log.genllvm(gen.compile())
- return gen.create_module(exe_name)
+ filename = gen.gen_llvm_source()
+ #log.genllvm(open(filename).read())
+ return gen.create_module(filename, exe_name)
def llvm_is_on_path():
try:
@@ -182,19 +180,19 @@
return False
return True
-def compile_module(function, annotate, view=False, embedexterns=True, exe_name=None):
+def compile_module(function, annotation, view=False, embedexterns=True, exe_name=None):
t = Translator(function)
- a = t.annotate(annotate)
+ a = t.annotate(annotation)
t.specialize()
if view:
t.view()
return genllvm(t, embedexterns=embedexterns, exe_name=exe_name)
-def compile_function(function, annotate, view=False, embedexterns=True, exe_name=None):
- mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name)
+def compile_function(function, annotation, view=False, embedexterns=True, exe_name=None):
+ mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name)
return getattr(mod, function.func_name + "_wrapper")
-def compile_module_function(function, annotate, view=False, embedexterns=True, exe_name=None):
- mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name)
+def compile_module_function(function, annotation, view=False, embedexterns=True, exe_name=None):
+ mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name)
f = getattr(mod, function.func_name + "_wrapper")
return mod, f
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 Sun Aug 7 18:23:24 2005
@@ -24,7 +24,9 @@
""")
-for exc in "ZeroDivisionError OverflowError ValueError".split():
+
+#prepage exceptions
+for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL
extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """
fastcc void %%__prepare_%(exc)s() {
%%exception_value = call fastcc %%structtype.object* %%instantiate_%(exc)s()
@@ -37,23 +39,104 @@
""" % locals())
+
+#binary with ZeroDivisionError only
for func_inst in "floordiv_zer:div mod_zer:rem".split():
func, inst = func_inst.split(':')
for type_ in "int uint".split():
extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """
fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) {
+
+ ;zerodiv test
%%cond = seteq %(type_)s %%y, 0
br bool %%cond, label %%is_0, label %%is_not_0
+is_0:
+ call fastcc void %%__prepare_ZeroDivisionError()
+ unwind
+
is_not_0:
%%z = %(inst)s %(type_)s %%x, %%y
ret %(type_)s %%z
-is_0:
- call fastcc void %%__prepare_ZeroDivisionError()
+}
+
+""" % locals())
+
+
+ovf_test = """
+ ;overflow test
+ %%cond2 = setge int %%x2, 0
+ br bool %%cond2, label %%return_block, label %%block2
+block2:
+ %%tmp = sub int 0, %%x2
+ %%cond3 = setne int %%x2, %%tmp
+ br bool %%cond3, label %%return_block, label %%ovf
+ovf:
+ call fastcc void %%__prepare_OverflowError()
unwind
+
+"""
+
+#unary with OverflowError only
+
+extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """
+fastcc int %%int_neg_ovf(int %%x) {
+block1:
+ %%x2 = sub int 0, %%x
+ %(ovf_test)s
+return_block:
+ ret int %%x2
+}
+
+""" % locals())
+
+extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """
+fastcc int %%int_abs_ovf(int %%x) {
+block0:
+ %%cond1 = setge int %%x, 0
+ br bool %%cond1, label %%return_block, label %%is_negative
+block1:
+ %%x2 = sub int 0, %%x
+ %(ovf_test)s
+return_block:
+ %%result = phi int [%%x, %%block0], [%%x2, %%block1], [%%x2, %%block2]
+ ret int %%result
}
""" % locals())
+
#XXX TODO
-#src/int.h:#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \
-#src/int.h:#define OP_INT_MOD_OVF_ZER(x,y,r,err)
+
+#overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) ok else _OVF()
+
+#binary with overflow
+#define OP_INT_ADD_OVF(x,y,r,err) \
+#define OP_INT_SUB_OVF(x,y,r,err) \
+#define OP_INT_MUL_OVF(x,y,r,err) \
+#define OP_INT_MUL_OVF(x,y,r,err) \
+#define OP_INT_FLOORDIV_OVF(x,y,r,err) \
+#define OP_INT_MOD_OVF(x,y,r,err) \
+
+#binary with overflow and zerodiv
+#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \
+#define OP_INT_MOD_OVF_ZER(x,y,r,err) \
+
+#shift
+#define OP_INT_LSHIFT_OVF(x,y,r,err) \
+#define OP_INT_LSHIFT_OVF_VAL(x,y,r,err) \
+#define OP_INT_RSHIFT_VAL(x,y,r,err) \
+#define OP_INT_LSHIFT_VAL(x,y,r,err) \
+
+
+#DONE
+
+#binary with zerodivisionerror only
+#define OP_INT_FLOORDIV_ZER(x,y,r,err) \
+#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \
+#define OP_INT_MOD_ZER(x,y,r,err) \
+#define OP_UINT_MOD_ZER(x,y,r,err) \
+
+#unary with overflow only
+#define OP_INT_ABS_OVF(x,r,err) \ untested
+#define OP_INT_NEG_OVF(x,r,err) \ untested
+
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 Sun Aug 7 18:23:24 2005
@@ -4,6 +4,8 @@
from pypy.translator.test.snippet import try_raise_choose
from pypy.rpython.rarithmetic import r_uint
+import sys
+
class TestException(Exception):
pass
@@ -136,6 +138,30 @@
for i in (0,50,100):
assert f(i) == zerodivrem_uint(i)
+def test_neg_int_ovf():
+ py.test.skip("When does int_neg_ovf get generated")
+ def neg_int_ovf(n):
+ try:
+ r=-n
+ except OverflowError:
+ return 123
+ return r
+ f = compile_function(neg_int_ovf, [int])
+ for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint):
+ assert f(i) == neg_int_ovf(i)
+
+def test_abs_int_ovf():
+ py.test.skip("When does int_abs_ovf get generated")
+ def abs_int_ovf(n):
+ try:
+ r=abs(n)
+ except OverflowError:
+ return 123
+ return r
+ f = compile_function(abs_int_ovf, [int], True)
+ for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint):
+ assert f(i) == abs_int_ovf(i)
+
def test_reraise1():
def fn(n):
lst = range(10)
More information about the Pypy-commit
mailing list