[pypy-svn] r22794 - in pypy/dist/pypy/translator/llvm: . backendopt externs externs/test module

rxe at codespeak.net rxe at codespeak.net
Sat Jan 28 15:44:08 CET 2006


Author: rxe
Date: Sat Jan 28 15:43:57 2006
New Revision: 22794

Added:
   pypy/dist/pypy/translator/llvm/module/protos.h
Removed:
   pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py
Modified:
   pypy/dist/pypy/translator/llvm/exception.py
   pypy/dist/pypy/translator/llvm/externs/   (props changed)
   pypy/dist/pypy/translator/llvm/externs/ringbuffer.py
   pypy/dist/pypy/translator/llvm/externs/test/   (props changed)
   pypy/dist/pypy/translator/llvm/externs/test/test_ringbuffer.py
   pypy/dist/pypy/translator/llvm/externs2ll.py
   pypy/dist/pypy/translator/llvm/funcnode.py
   pypy/dist/pypy/translator/llvm/gc.py
   pypy/dist/pypy/translator/llvm/module/boehm.h
   pypy/dist/pypy/translator/llvm/module/excsupport.py
   pypy/dist/pypy/translator/llvm/module/genexterns.c
   pypy/dist/pypy/translator/llvm/opwriter.py
Log:
Not sure of the merits of this: replaced the removeexcmallocs transformation
and ll code and replaced it with a rpython version.

Far too much code need modified for this.



Modified: pypy/dist/pypy/translator/llvm/exception.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/exception.py	(original)
+++ pypy/dist/pypy/translator/llvm/exception.py	Sat Jan 28 15:43:57 2006
@@ -2,8 +2,8 @@
 
 from pypy.translator.llvm.codewriter import DEFAULT_CCONV
 from pypy.translator.llvm.backendopt.exception import create_exception_handling
-from pypy.translator.llvm.module.excsupport import \
-     ringbuffer_decl, ringbuffer_code, invokeunwind_code, explicit_code
+from pypy.translator.llvm.module.excsupport import invokeunwind_code, \
+                                                   explicit_code
 
 def repr_if_variable(db, arg):
     if isinstance(arg, Variable):
@@ -89,7 +89,7 @@
         returntype, entrypointname = entrynode.getdecl().split('%', 1)
         noresult = self._noresult(returntype)
         cconv = DEFAULT_CCONV
-        return invokeunwind_code % locals() + ringbuffer_code
+        return invokeunwind_code % locals()
 
     def invoke(self, codewriter, targetvar, tail_, cconv, returntype,
                functionref, args, label, except_label):
@@ -182,13 +182,13 @@
         self.invoke_count = 0
 
     def llvm_declcode(self):
-        return ringbuffer_decl
+        return ''
     
     def llvm_implcode(self, entrynode):
         returntype, entrypointname = entrynode.getdecl().split('%', 1)
         noresult = self._noresult(returntype)
         cconv = DEFAULT_CCONV
-        return explicit_code % locals() + ringbuffer_code
+        return explicit_code % locals()
  
     def transform(self, translator, graph=None):
         if graph:

Modified: pypy/dist/pypy/translator/llvm/externs/ringbuffer.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs/ringbuffer.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs/ringbuffer.py	Sat Jan 28 15:43:57 2006
@@ -1,22 +1,29 @@
-from pypy.rpython.memory.lladdress import raw_malloc
+from pypy.rpython.memory import lladdress
+from pypy.rpython.lltypesystem import lltype, llmemory
 
-class RingBufferData:
-    size          = 8192
-    entry_maxsize = 16
-
-    def __init__(self):
-        self.index = 0
-    def init(self):
-        self.data = raw_malloc(self.size + self.entry_maxsize)
-
-ringbuffer = RingBufferData()
-
-def initialise():
-    ringbuffer.init()
-
-def malloc_exception(nbytes):
-    assert nbytes <= ringbuffer.entry_maxsize
-    addr = ringbuffer.data + ringbuffer.index
-    ringbuffer.index = (ringbuffer.index + nbytes) & (ringbuffer.size - 1)
+# Cant store in class
+size = 8192
+entry_maxsize = 16
+ringbufdata = lltype.malloc(lltype.GcArray(llmemory.Address), 1)
+ringbufindex = lltype.malloc(lltype.GcArray(lltype.Signed), 1)
+
+def ringbuffer_initialise():
+    ringbufdata[0] = lladdress.raw_malloc(size + entry_maxsize)
+
+def ringbuffer_malloc(nbytes):
+    assert nbytes <= entry_maxsize
+    addr = ringbufdata[0] + ringbufindex[0]
+    ringbufindex[0] = (ringbufindex[0] + nbytes) & (size - 1)
     return addr
 
+# XXX would be nice to support something like this
+# ringbufindex = lltype.malloc(lltype.GcArray(lltype.Char), size + entry_maxsize)
+
+# def ringbuffer_initialise():
+#     pass
+
+# def ringbuffer_malloc(nbytes):
+#     assert nbytes <= entry_maxsize
+#     addr = lladdress.get_address_of_object(ringbufdata[ringbufindex[0]])
+#     ringbufindex[0] = (ringbufindex[0] + nbytes) & (size - 1)
+#     return addr

Modified: pypy/dist/pypy/translator/llvm/externs/test/test_ringbuffer.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs/test/test_ringbuffer.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs/test/test_ringbuffer.py	Sat Jan 28 15:43:57 2006
@@ -1,11 +1,22 @@
 import py
+from pypy.tool.udir import udir
+
 from pypy.translator.llvm.test.runtest import compile_function as compile
 from pypy.translator.llvm.externs import ringbuffer
+from pypy.translator.llvm import genllvm
 
+def teardown_module(self):
+    for n in ["ccode.c", "ccode.ll"]:
+        f = udir.join(n)
+        if f.check(exists=1):
+            f.remove()
+    genllvm.GenLLVM.llexterns_header = None
+    genllvm.GenLLVM.llexterns_functions = None
+    
 def test_malloc_something():
     def f(value):
-        ringbuffer.initialise()
-        buf = ringbuffer.malloc_exception(value)
+        ringbuffer.ringbuffer_initialise()
+        buf = ringbuffer.ringbuffer_malloc(value)
         buf.signed[0] = 10
         return buf.signed[0]
 

Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py	Sat Jan 28 15:43:57 2006
@@ -24,8 +24,8 @@
     "%LLVM_RPython_StartupCode",
     ]
 
-def get_genexterns_path():
-    return os.path.join(get_llvm_cpath(), "genexterns.c")
+def get_module_file(name):
+    return os.path.join(get_llvm_cpath(), name)
 
 def get_ll(ccode, function_names):
     function_names += support_functions
@@ -101,6 +101,7 @@
         raise "Can't compile external function code (llcode.c): ERROR:", llcode
     return decl, impl
 
+
 def setup_externs(db):
     rtyper = db.translator.rtyper
     from pypy.translator.c.extfunc import predeclare_all
@@ -123,6 +124,20 @@
         else:
             assert False, "unhandled predeclare %s %s %s" % (c_name, type(obj), obj)
 
+    def annotatehelper(func, *argtypes):
+        graph = db.translator.rtyper.annotate_helper(func, argtypes)
+        fptr = rtyper.getcallable(graph)
+        c = inputconst(lltype.typeOf(fptr), fptr)
+        db.prepare_arg_value(c)
+        decls.append(("ll_" + func.func_name, graph))
+        return graph.name
+
+    if hasattr(db.gcpolicy, 'exc_useringbuf') and db.gcpolicy.exc_useringbuf:
+        from pypy.translator.llvm.externs import ringbuffer as rb
+        g = annotatehelper(rb.ringbuffer_initialise)
+        db.gcpolicy.ringbuf_malloc_name = \
+                 annotatehelper(rb.ringbuffer_malloc, lltype.Signed)
+
     return decls
 
 def get_c_cpath():
@@ -179,6 +194,9 @@
             assert False, "unhandled extern_decls %s %s %s" % (c_name, type(obj), obj)
 
 
+    # append protos
+    ccode.append(open(get_module_file('protos.h')).read())
+
     # include this early to get constants and macros for any further includes
     ccode.append('#include <Python.h>\n')
 
@@ -186,7 +204,6 @@
     ccode.append('%s\n' % db.gcpolicy.genextern_code())
     
     # append our source file
-    ccode = "".join(ccode)
-    ccode += open(get_genexterns_path()).read()
-    
-    return get_ll(ccode, function_names)
+    ccode.append(open(get_module_file('genexterns.c')).read())
+
+    return get_ll("".join(ccode), function_names)

Modified: pypy/dist/pypy/translator/llvm/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/funcnode.py	Sat Jan 28 15:43:57 2006
@@ -4,7 +4,6 @@
 from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode
 from pypy.translator.llvm.opwriter import OpWriter
 from pypy.translator.llvm.log import log 
-from pypy.translator.llvm.backendopt.removeexcmallocs import remove_exception_mallocs
 from pypy.translator.unsimplify import remove_double_links
 log = log.funcnode
 
@@ -72,9 +71,6 @@
 
     def post_setup_transform(self):
         self.db.exceptionpolicy.transform(self.db.translator, self.graph)
-	import sys
-	if sys.maxint == 2**31-1:	#XXX not yet 64bit compatible
-        	remove_exception_mallocs(self.db.translator, self.graph, self.ref)
         remove_double_links(self.db.translator, self.graph)
     
     def writedecl(self, codewriter): 

Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py	(original)
+++ pypy/dist/pypy/translator/llvm/gc.py	Sat Jan 28 15:43:57 2006
@@ -9,7 +9,7 @@
         raise Exception, 'GcPolicy should not be used directly'
     
     def genextern_code(self):
-        return ""
+        return ''
     
     def gc_libraries(self):
         return []
@@ -53,12 +53,20 @@
         #XXX memset
         
 class BoehmGcPolicy(GcPolicy):
-    def __init__(self, db):
+
+    def __init__(self, db, exc_useringbuf=False):
         self.db = db
         self.n_malloced = 0
+        self.exc_useringbuf = exc_useringbuf
         
     def genextern_code(self):
-        return '#include "boehm.h"'
+        r = '#include "boehm.h"\n'
+
+        if self.exc_useringbuf:
+            r += '#define __GC_SETUP_CODE__ ll_ringbuffer_initialise();\n'
+        else:
+            r += '#define __GC_SETUP_CODE__\n'
+        return r
     
     def gc_libraries(self):
         return ['gc', 'pthread'] # XXX on windows?
@@ -71,7 +79,13 @@
     return GC_get_heap_size()
 '''
 
-    def _malloc(self, codewriter, targetvar, size=1, atomic=False):
+    def get_count(self, inc=False):
+        if inc:
+            self.n_malloced += 1
+        return '_%d' % self.n_malloced
+
+    def _malloc(self, codewriter, targetvar, size=1, atomic=False,
+                exc_flag=False):
         """ assumes malloc of word size """
         # XXX Boehm aligns on 8 byte boundaries
     	if sys.platform == 'linux2' and sys.maxint == 2**63-1:
@@ -79,9 +93,18 @@
 	else:
             boundary_size = 0
 
+        word = self.db.get_machine_word()
         uword = self.db.get_machine_uword()
-        fnname = '%pypy_malloc' + (atomic and '_atomic' or '')
-        codewriter.call(targetvar, 'sbyte*', fnname, [uword], [size])
+
+        if self.exc_useringbuf and exc_flag:
+            fnname = '%pypy_' + self.ringbuf_malloc_name
+        else:
+            fnname = '%pypy_malloc' + (atomic and '_atomic' or '')
+
+        # malloc_size is unsigned right now
+        sizei = '%malloc_sizei' + self.get_count()        
+        codewriter.cast(sizei, uword, size, word)
+        codewriter.call(targetvar, 'sbyte*', fnname, [word], [sizei])
         
         if atomic:
             codewriter.call(None, 'void', '%llvm.memset',
@@ -89,18 +112,17 @@
                             [targetvar, 0, size, boundary_size],
                             cconv='ccc')        
 
-    def malloc(self, codewriter, targetvar, type_, size=1, atomic=False):
+    def malloc(self, codewriter, targetvar, type_, size=1, atomic=False,
+               exc_flag=False):
         uword = self.db.get_machine_uword()
-        self.n_malloced += 1
-        cnt = '_%d' % self.n_malloced
-        malloc_ptr = '%malloc_ptr' + cnt
-        malloc_size = '%malloc_size' + cnt
-        malloc_sizeu = '%malloc_sizeu' + cnt
+        malloc_ptr = '%malloc_ptr' + self.get_count(True)
+        malloc_size = '%malloc_size' + self.get_count()
+        malloc_sizeu = '%malloc_sizeu' + self.get_count()
         
         codewriter.getelementptr(malloc_size, type_, 'null',
                                  [(uword, size)], getptr=False)
         codewriter.cast(malloc_sizeu, type_, malloc_size, uword)
-        self._malloc(codewriter, malloc_ptr, malloc_sizeu, atomic)
+        self._malloc(codewriter, malloc_ptr, malloc_sizeu, atomic, exc_flag)
         codewriter.cast(targetvar, 'sbyte*', malloc_ptr, type_)            
 
     def var_malloc(self, codewriter, targetvar,
@@ -108,13 +130,11 @@
 
         word = lentype = self.db.get_machine_word()
         uword = self.db.get_machine_uword()
-        self.n_malloced += 1
-        cnt = '_%d' % self.n_malloced
-        malloc_ptr = '%malloc_ptr' + cnt
-        malloc_size = '%malloc_size' + cnt
-        malloc_sizeu = '%malloc_sizeu' + cnt
-        actuallen = '%actuallen' + cnt
-        arraylength = '%arraylength' + cnt
+        malloc_ptr = '%malloc_ptr' + self.get_count(True)
+        malloc_size = '%malloc_size' + self.get_count()
+        malloc_sizeu = '%malloc_sizeu' + self.get_count()
+        actuallen = '%actuallen' + self.get_count()
+        arraylength = '%arraylength' + self.get_count()
         
         ARRAY, indices_to_array = node.var_malloc_info()
         

Modified: pypy/dist/pypy/translator/llvm/module/boehm.h
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/boehm.h	(original)
+++ pypy/dist/pypy/translator/llvm/module/boehm.h	Sat Jan 28 15:43:57 2006
@@ -15,11 +15,11 @@
 
 #define USING_BOEHM_GC
 
-char *pypy_malloc(unsigned long size) {
+char *pypy_malloc(long size) {
   return GC_MALLOC(size);
 }
 
-char *pypy_malloc_atomic(unsigned long size) {
+char *pypy_malloc_atomic(long size) {
   return GC_MALLOC_ATOMIC(size);
 }
 

Modified: pypy/dist/pypy/translator/llvm/module/excsupport.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/excsupport.py	(original)
+++ pypy/dist/pypy/translator/llvm/module/excsupport.py	Sat Jan 28 15:43:57 2006
@@ -1,37 +1,3 @@
-RINGBUFFER_SIZE          = 8192
-RINGBUFFER_ENTRY_MAXSIZE = 16
-RINGBUFFER_OVERSIZE      = RINGBUFFER_SIZE + RINGBUFFER_ENTRY_MAXSIZE
-
-ringbuffer_decl = """
-; 8208=8192+16 in the next line because the last one (16 bytes maxsize) might
-; start at 8190 for instance. [RINGBUFFER_SIZE + RINGBUFFER_ENTRY_MAXSIZE]
-
-%%exception_ringbuffer = internal global [%s x sbyte] zeroinitializer
-%%exception_ringbuffer_index = internal global uint 0
-""" % (RINGBUFFER_SIZE + RINGBUFFER_ENTRY_MAXSIZE)
-
-ringbuffer_code = '''
-internal fastcc sbyte* %%malloc_exception(uint %%nbytes) {
-    %%cond = setle uint %%nbytes, %d
-    br bool %%cond, label %%then, label %%else
-
-then:
-    %%tmp.3 = load uint* %%exception_ringbuffer_index
-    %%tmp.4 = getelementptr [%d x sbyte]* %%exception_ringbuffer, int 0, uint %%tmp.3
-    %%tmp.6 = add uint %%tmp.3, %%nbytes
-    %%tmp.7 = and uint %%tmp.6, %d
-    store uint %%tmp.7, uint* %%exception_ringbuffer_index
-    ret sbyte* %%tmp.4
-
-else:
-    %%tmp.8  = call ccc sbyte* %%pypy_malloc(uint %%nbytes)
-    ret sbyte* %%tmp.8
-}
-''' % (RINGBUFFER_ENTRY_MAXSIZE, RINGBUFFER_OVERSIZE, RINGBUFFER_SIZE - 1)
-
-import sys
-if sys.maxint != 2**31-1: #XXX need to move the ringbuffer code to another level anyway
-    ringbuffer_decl = ringbuffer_code = ''
 
 invokeunwind_code = '''
 ccc %(returntype)s%%__entrypoint__%(entrypointname)s {

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	Sat Jan 28 15:43:57 2006
@@ -1,24 +1,4 @@
 
-// we hand craft these in module/support.ll
-char *RPyString_AsString(RPyString*);
-long RPyString_Size(RPyString*);
-RPyString *RPyString_FromString(char *);
-int RPyExceptionOccurred(void);
-char* LLVM_RPython_StartupCode(void);
-
-#define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg)
-
-// XXX 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);
-#ifdef RPyListOfString
-  RPyListOfString *_RPyListOfString_New(long);
-  void _RPyListOfString_SetItem(RPyListOfString *, int, RPyString *);
-#endif
-// XXX end of proto hacks
-
 // overflows/zeros/values raising operations
 #include "raisingop.h"
 
@@ -116,6 +96,9 @@
   if (error != NULL) {
     return 0;
   }
+  
+  __GC_SETUP_CODE__
+
   return 1;
 }
 

Added: pypy/dist/pypy/translator/llvm/module/protos.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/module/protos.h	Sat Jan 28 15:43:57 2006
@@ -0,0 +1,22 @@
+
+// we hand craft these in module/support.ll
+char *RPyString_AsString(RPyString*);
+long RPyString_Size(RPyString*);
+RPyString *RPyString_FromString(char *);
+int RPyExceptionOccurred(void);
+char* LLVM_RPython_StartupCode(void);
+
+#define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg)
+
+// XXX 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);
+#ifdef RPyListOfString
+  RPyListOfString *_RPyListOfString_New(long);
+  void _RPyListOfString_SetItem(RPyListOfString *, int, RPyString *);
+#endif
+void ll_ringbuffer_initialise(void);
+
+// XXX end of proto hacks

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Sat Jan 28 15:43:57 2006
@@ -265,8 +265,15 @@
 
     def malloc(self, opr):
         arg_type = opr.op.args[0].value
+
+        # XXX hack better to look at the actual structure
+        name = str(opr.op.args[0])
+        exc = False
+        if 'Exception' in name or 'Error' in name:
+            exc = True
+
         self.db.gcpolicy.malloc(self.codewriter, opr.retref, opr.rettype,
-                                atomic=arg_type._is_atomic())
+                                atomic=arg_type._is_atomic(), exc_flag=exc)
 
     def malloc_varsize(self, opr):
 
@@ -489,14 +496,6 @@
     # 
     # XXX exception specific - move to policy?
 
-    def malloc_exception(self, opr): 
-        tmpvar1, tmpvar2, tmpvar3 = self._tmp(3)
-        cw = self.codewriter
-        cw.getelementptr(tmpvar1, opr.rettype, "null", [("int", 1)], getptr=False)
-        cw.cast(tmpvar2, opr.rettype, tmpvar1, 'uint')
-        cw.call(tmpvar3, 'sbyte*', '%malloc_exception', ['uint'], [tmpvar2])
-        cw.cast(opr.retref, 'sbyte*', tmpvar3, opr.rettype)
-
     def last_exception_type_ptr(self, opr):
         op = opr.op
         e = self.db.translator.rtyper.getexceptiondata()



More information about the Pypy-commit mailing list