[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