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

rxe at codespeak.net rxe at codespeak.net
Mon Nov 21 16:37:41 CET 2005


Author: rxe
Date: Mon Nov 21 16:37:34 2005
New Revision: 20134

Modified:
   pypy/dist/pypy/translator/llvm/arraynode.py
   pypy/dist/pypy/translator/llvm/build_llvm_module.py
   pypy/dist/pypy/translator/llvm/database.py
   pypy/dist/pypy/translator/llvm/exception.py
   pypy/dist/pypy/translator/llvm/externs2ll.py
   pypy/dist/pypy/translator/llvm/funcnode.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/module/genexterns.c
   pypy/dist/pypy/translator/llvm/module/support.py
   pypy/dist/pypy/translator/llvm/node.py
   pypy/dist/pypy/translator/llvm/opwriter.py
   pypy/dist/pypy/translator/llvm/structnode.py
   pypy/dist/pypy/translator/llvm/test/test_extfunc.py
Log:
Various fixes to problems related to thread.error exceptions being optimised
away by llvm.  Also refactored entry point some more.

* Generate %raisePyExc_xxx() instead of hand coding it.

* Dont use "." in our names since we are calling back from C code (use "_"
  instead, which is still readable).

* Avoid decomposing strings when we have the database.


* Sanitized entry point - now based on database instead of string comparision.

* Replaced include gc/gc.h with an extern as per arigo's suggestions.

* Enable logging in build_llvm




Modified: pypy/dist/pypy/translator/llvm/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/arraynode.py	(original)
+++ pypy/dist/pypy/translator/llvm/arraynode.py	Mon Nov 21 16:37:34 2005
@@ -26,8 +26,8 @@
         else:
             name += str(arraytype)
 
-        self.ref = self.make_ref('%arraytype.', name)
-        self.constructor_ref = self.make_ref('%new.array.', name)
+        self.ref = self.make_ref('%arraytype_', name)
+        self.constructor_ref = self.make_ref('%new_array_', name)
         self.constructor_decl = "%s * %s(%s %%len)" % \
                                 (self.ref,
                                  self.constructor_ref,
@@ -66,7 +66,7 @@
         assert isinstance(array, lltype.Array)
         self.db = db
         self.array = array
-        self.ref = "%arraytype.Void"
+        self.ref = "%arraytype_Void"
 
     def writedatatypedecl(self, codewriter):
         td = "%s = type { %s }" % (self.ref, self.db.get_machine_word())

Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/build_llvm_module.py	(original)
+++ pypy/dist/pypy/translator/llvm/build_llvm_module.py	Mon Nov 21 16:37:34 2005
@@ -128,7 +128,7 @@
         try:
             try:
                 for cmd in cmds:
-                    #log.build(cmd)
+                    log.build(cmd)
                     cmdexec(cmd)
                 if pyxfile:
                     make_c_from_pyxfile(pyxfile)

Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Mon Nov 21 16:37:34 2005
@@ -221,7 +221,7 @@
 
     def setup_all(self):
         while self._pendingsetup: 
-            node = self._pendingsetup.pop()
+            node = self._pendingsetup.pop(0)
             #log.settingup(node)
             node.setup()
 

Modified: pypy/dist/pypy/translator/llvm/exception.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/exception.py	(original)
+++ pypy/dist/pypy/translator/llvm/exception.py	Mon Nov 21 16:37:34 2005
@@ -43,8 +43,7 @@
         return r + ' null'
 
     def _nonoderesult(self, node):
-        decl = node.getdecl()
-        returntype, name = decl.split(' ', 1)
+        returntype, name, dummy = node.getdecl_parts()
         noresult = self._noresult(returntype)
         return noresult
 

Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py	Mon Nov 21 16:37:34 2005
@@ -15,9 +15,7 @@
     "%raisePyExc_OverflowError",
     "%raisePyExc_ZeroDivisionError",
     "%raisePyExc_RuntimeError",
-    "%prepare_ZeroDivisionError",
-    "%prepare_OverflowError",
-    "%prepare_ValueError",
+    "%raisePyExc_thread_error",
     "%RPyString_FromString",
     "%RPyString_AsString",
     "%RPyString_Size",
@@ -101,8 +99,7 @@
         raise "Can't compile external function code (llcode.c): ERROR:", llcode
     return decl, impl
 
-
-def post_setup_externs(db):
+def setup_externs(db):
     rtyper = db.translator.rtyper
     from pypy.translator.c.extfunc import predeclare_all
 
@@ -125,14 +122,13 @@
 
     return decls
 
-
 def path_join(root_path, *paths):
     path = root_path
     for p in paths:
         path = os.path.join(path, p)
     return path
 
-def generate_llfile(db, extern_decls):
+def generate_llfile(db, extern_decls, entrynode):
     ccode = []
     function_names = []
         
@@ -147,8 +143,8 @@
     for k, v in db.obj2node.items():
         try:
             if isinstance(lltype.typeOf(k), lltype.FuncType):
-                if k._name == "entry_point":
-                    predeclarefn("entry_point", v.get_ref())
+                if v == entrynode and k._name == "entry_point":
+                    predeclarefn("__ENTRY_POINT__", v.get_ref())
                     ccode.append('#define ENTRY_POINT_DEFINED 1\n\n')
                     break
         except TypeError, exc:
@@ -163,7 +159,11 @@
             c = inputconst(lltype.typeOf(funcptr), funcptr)
             predeclarefn(c_name, db.repr_arg(c))
         elif isinstance(lltype.typeOf(obj), lltype.Ptr):
-            predeclarefn(c_name, db.obj2node[obj._obj].ref)
+            if c_name.startswith("RPyExc_"):
+                c_name = c_name[1:]
+                ccode.append("void raise%s(char *);\n" % c_name)
+            else:
+                predeclarefn(c_name, db.obj2node[obj._obj].ref)                
         else:
             assert False, "unhandled extern_decls %s %s %s" % (c_name, type(obj), obj)
 

Modified: pypy/dist/pypy/translator/llvm/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/funcnode.py	Mon Nov 21 16:37:34 2005
@@ -122,8 +122,7 @@
     
     # ______________________________________________________________________
     # writing helpers for entry points
-
-    def getdecl(self):
+    def getdecl_parts(self):
         startblock = self.graph.startblock
         returnblock = self.graph.returnblock
         startblock_inputargs = [a for a in startblock.inputargs
@@ -132,10 +131,12 @@
         inputargs = self.db.repr_arg_multi(startblock_inputargs)
         inputargtypes = self.db.repr_arg_type_multi(startblock_inputargs)
         returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0])
-        result = "%s %s" % (returntype, self.ref)
         args = ["%s %s" % item for item in zip(inputargtypes, inputargs)]
-        result += "(%s)" % ", ".join(args)
-        return result 
+        return returntype, self.ref, args
+
+    def getdecl(self):
+        returntype, ref, args = self.getdecl_parts()
+        return "%s %s(%s)" % (returntype, ref, ", ".join(args))
 
     def write_block(self, codewriter, block):
         self.write_block_phi_nodes(codewriter, block)

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Mon Nov 21 16:37:34 2005
@@ -8,9 +8,10 @@
 from pypy.tool.udir import udir
 from pypy.translator.llvm.codewriter import CodeWriter
 from pypy.translator.llvm import extfuncnode
-from pypy.translator.llvm.module.support import extdeclarations, extfunctions
+from pypy.translator.llvm.module.support import \
+     extdeclarations, extfunctions, write_raise_exc
 from pypy.translator.llvm.node import LLVMNode
-from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile
+from pypy.translator.llvm.externs2ll import setup_externs, generate_llfile
 from pypy.translator.llvm.gc import GcPolicy
 from pypy.translator.llvm.exception import ExceptionPolicy
 from pypy.translator.translator import Translator
@@ -79,28 +80,28 @@
 
         self._checkpoint()
 
+        # set up externs nodes
+        extern_decls = setup_externs(self.db)
+        self.translator.rtyper.specialize_more_blocks()
+        self.db.setup_all()
+        self._checkpoint('setup_all externs')
+        
         # get entry point
         entry_point, func_name = self.get_entry_point(func)
         self._checkpoint('get_entry_point')
-
-        # open file & create codewriter
-        codewriter, filename = self.create_codewrite(func_name)
-        self._checkpoint('open file and create codewriter')
-
+        
         # set up all nodes
         self.db.setup_all()
         self.entrynode = self.db.set_entrynode(entry_point)
         self._checkpoint('setup_all first pass')
 
-        # post set up nodes 
-        extern_decls = post_setup_externs(self.db)
-        self.translator.rtyper.specialize_more_blocks()
-        self.db.setup_all()
-        self._checkpoint('setup_all second pass')
-
         self._print_node_stats()
 
-        # create ll file from c code 
+        # open file & create codewriter
+        codewriter, filename = self.create_codewrite(func_name)
+        self._checkpoint('open file and create codewriter')
+
+        # create ll file from c code
         self.setup_externs(extern_decls)
         self._checkpoint('setup_externs')
     
@@ -147,6 +148,7 @@
         # write external function implementations
         codewriter.header_comment('External Function Implementation')
         codewriter.append(self.llexterns_functions)
+        self.write_extern_impls(codewriter, extern_decls)
 
         self._checkpoint('write external functions')
 
@@ -201,7 +203,9 @@
         if self.llexterns_header is None:
             assert self.llexterns_functions is None
             self.llexterns_header, self.llexterns_functions = \
-                                   generate_llfile(self.db, extern_decls)
+                                   generate_llfile(self.db,
+                                                   extern_decls,
+                                                   self.entrynode)
 
     def create_codewrite(self, func_name):
         # prevent running the same function twice in a test
@@ -223,6 +227,13 @@
 
                 l = "%%%s = type %s" % (c_name, self.db.repr_type(obj))
                 codewriter.append(l)
+  
+    def write_extern_impls(self, codewriter, extern_decls):
+        for c_name, obj in extern_decls:
+            if c_name.startswith("RPyExc_"):
+                c_name = c_name[1:]
+                exc_repr = self.db.repr_constant(obj)[1]
+                write_raise_exc(c_name, exc_repr, codewriter)
 
     def _checkpoint(self, msg=None):
         if not self.logging:

Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/genexterns.c	(original)
+++ pypy/dist/pypy/translator/llvm/module/genexterns.c	Mon Nov 21 16:37:34 2005
@@ -1,25 +1,17 @@
 
-// We hand craft these in module/support.ll
+// we hand craft these in module/support.ll
 char *RPyString_AsString(RPyString*);
 int RPyString_Size(RPyString*);
 RPyString *RPyString_FromString(char *);
 int RPyExceptionOccurred(void);
 
-void raisePyExc_IOError(char *);
-void raisePyExc_ValueError(char *);
-void raisePyExc_OverflowError(char *);
-void raisePyExc_ZeroDivisionError(char *);
-void raisePyExc_RuntimeError(char *);
-void raisePyExc_thread_error(char *);
-
 #define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg)
 
-// Generated by rpython - argggh have to feed in prototypes
+// generated by rpython - argggh have to feed in prototypes
 RPyFREXP_RESULT *ll_frexp_result(double, int);
 RPyMODF_RESULT *ll_modf_result(double, double);
 RPySTAT_RESULT *ll_stat_result(int, int, int, int, int, int, int, int, int, int);
 void RPYTHON_RAISE_OSERROR(int error);
-
 RPyListOfString *_RPyListOfString_New(int);
 void _RPyListOfString_SetItem(RPyListOfString *, int, RPyString *);
 
@@ -27,25 +19,25 @@
 #include <locale.h>
 #include <ctype.h>
 
-//the placeholder in the next line gets replaced by the actual python.h path
+// the placeholder in the next line gets replaced by the actual python.h path
 #include __PYTHON_H__
 
 // overflows/zeros/values raising operations
 __RAISING_OPS__
 
-// Append some genc files here manually from python
+// append some genc files here manually from python
 __INCLUDE_FILES__
 
 #ifdef ENTRY_POINT_DEFINED
 
-#include <gc/gc.h>
+extern GC_all_interior_pointers;
 
 char *RPython_StartupCode() {
   GC_all_interior_pointers = 0;
   return NULL;
 }
 
-int entry_point(RPyListOfString *);
+int __ENTRY_POINT__(RPyListOfString *);
 
 int main(int argc, char *argv[])
 {
@@ -67,7 +59,7 @@
       _RPyListOfString_SetItem(list, i, s);
     }
 
-    exitcode = entry_point(list);
+    exitcode = __ENTRY_POINT__(list);
 
     if (RPyExceptionOccurred()) {
       goto error; // XXX see genc

Modified: pypy/dist/pypy/translator/llvm/module/support.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/support.py	(original)
+++ pypy/dist/pypy/translator/llvm/module/support.py	Mon Nov 21 16:37:34 2005
@@ -91,25 +91,11 @@
 }
 """
 
+def write_raise_exc(c_name, exc_repr, codewriter):
 
-# prepare exceptions
-for exc in "ZeroDivisionError OverflowError ValueError".split():
-    extfunctions += """
-internal fastcc void %%prepare_%(exc)s() {
-    %%exception_value = cast %%structtype.%(exc)s* %%structinstance.%(exc)s to %%RPYTHON_EXCEPTION*
-    %%tmp             = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0
-    %%exception_type  = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp
-    store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type
-    store %%RPYTHON_EXCEPTION* %%exception_value, %%RPYTHON_EXCEPTION** %%last_exception_value
-    ret void
-}
-""" % locals()
-
-for exc in "IOError ZeroDivisionError " \
-           "OverflowError ValueError RuntimeError".split():
-    extfunctions += """
-internal fastcc void %%raisePyExc_%(exc)s(sbyte* %%msg) {
-    %%exception_value = cast %%structtype.%(exc)s* %%structinstance.%(exc)s to %%RPYTHON_EXCEPTION*
+    l = """
+internal fastcc void %%raise%s(sbyte* %%msg) {
+    %%exception_value = cast %s to %%RPYTHON_EXCEPTION*
     %%tmp             = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0
     %%exception_type  = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp
     store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type
@@ -117,17 +103,6 @@
     call fastcc void %%unwind()
     ret void
 }
-""" % locals() 
-
-extfunctions += """
-internal fastcc void %raisePyExc_thread_error(sbyte* %msg) {
-    %exception_value = cast %structtype.error* %structinstance.error to %RPYTHON_EXCEPTION*
-    %tmp             = getelementptr %RPYTHON_EXCEPTION* %exception_value, int 0, uint 0
-    %exception_type  = load %RPYTHON_EXCEPTION_VTABLE** %tmp
-    store %RPYTHON_EXCEPTION_VTABLE* %exception_type, %RPYTHON_EXCEPTION_VTABLE** %last_exception_type
-    store %RPYTHON_EXCEPTION* %exception_value, %RPYTHON_EXCEPTION** %last_exception_value
-    call fastcc void %unwind()
-    ret void
-}
-"""
+""" % (c_name, exc_repr)
+    codewriter.append(l)
 

Modified: pypy/dist/pypy/translator/llvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/node.py	(original)
+++ pypy/dist/pypy/translator/llvm/node.py	Mon Nov 21 16:37:34 2005
@@ -11,7 +11,7 @@
             name = '"%s"' % name
             
         if name in self.nodename_count:
-            postfix = '.%d' % self.nodename_count[name]
+            postfix = '_%d' % self.nodename_count[name]
             self.nodename_count[name] += 1
         else:
             postfix = ''

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Mon Nov 21 16:37:34 2005
@@ -287,7 +287,8 @@
 
     def last_exception_type_ptr(self, op):
         e = self.db.translator.rtyper.getexceptiondata()
-        lltype_of_exception_type = ('%structtype.' + e.lltype_of_exception_type.TO.__name__ + '*')
+        # XXX Can we use database?
+        lltype_of_exception_type = ('%structtype_' + e.lltype_of_exception_type.TO.__name__ + '*')
         self.codewriter.load('%'+str(op.result), lltype_of_exception_type, '%last_exception_type')
 
     def invoke(self, op):
@@ -326,10 +327,12 @@
 
         e = self.db.translator.rtyper.getexceptiondata()
         ll_exception_match       = '%pypy_' + e.ll_exception_match.__name__
-        lltype_of_exception_type = ('%structtype.' +
+
+        # XXX Can we use database?
+        lltype_of_exception_type = ('%structtype_' +
                                     e.lltype_of_exception_type.TO.__name__
                                     + '*')
-        lltype_of_exception_value = ('%structtype.' +
+        lltype_of_exception_value = ('%structtype_' +
                                     e.lltype_of_exception_value.TO.__name__
                                     + '*')
 

Modified: pypy/dist/pypy/translator/llvm/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/structnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/structnode.py	Mon Nov 21 16:37:34 2005
@@ -12,7 +12,7 @@
         assert isinstance(struct, lltype.Struct)
         self.db = db
         self.struct = struct
-        prefix = '%structtype.'
+        prefix = '%structtype_'
         name = self.struct._name
         self.ref = self.make_ref(prefix, name)
         self.name = self.ref[len(prefix):]
@@ -41,7 +41,7 @@
 
     def __init__(self, db, struct): 
         super(StructVarsizeTypeNode, self).__init__(db, struct)
-        prefix = '%new.varsizestruct.'
+        prefix = '%new_varsizestruct_'
         self.constructor_ref = self.make_ref(prefix, self.name)
         self.constructor_decl = "%s * %s(%s %%len)" % \
                                 (self.ref,
@@ -91,7 +91,7 @@
         self.db = db
         self.value = value
         self.structtype = self.value._TYPE
-        prefix = '%structinstance.'
+        prefix = '%structinstance_'
         name = str(value).split()[1]
         self.ref = self.make_ref(prefix, name)
         self._get_ref_cache = None

Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_extfunc.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_extfunc.py	Mon Nov 21 16:37:34 2005
@@ -378,14 +378,13 @@
         ok1 = l.acquire(True)
         ok2 = l.acquire(False)
         l.release()
-        # XXX
-        #ok2_and_a_half = False
-        #try:
-        #    l.release()
-        #except thread.error:
-        #    ok2_and_a_half = True
-        #ok3 = l.acquire(False)
-        return ok1 and not ok2 #and ok2_and_a_half and ok3
+        ok2_and_a_half = False
+        try:
+            l.release()
+        except thread.error:
+            ok2_and_a_half = True
+        ok3 = l.acquire(False)
+        return ok1 and not ok2 and ok2_and_a_half and ok3
     f = compile_function(fn, [])
     res = f()
     assert res



More information about the Pypy-commit mailing list