[pypy-svn] r49055 - pypy/dist/pypy/translator/llvm

rxe at codespeak.net rxe at codespeak.net
Sat Nov 24 19:10:32 CET 2007


Author: rxe
Date: Sat Nov 24 19:10:31 2007
New Revision: 49055

Modified:
   pypy/dist/pypy/translator/llvm/database.py
   pypy/dist/pypy/translator/llvm/externs2ll.py
   pypy/dist/pypy/translator/llvm/extfuncnode.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/opwriter.py
Log:
try to make fastcc calling convention work again (not there yet)

Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Sat Nov 24 19:10:31 2007
@@ -72,9 +72,7 @@
     def create_constant_node(self, type_, value):
         node = None
         if isinstance(type_, lltype.FuncType):
-            if hasattr(value, '_external_name'):
-                node = ExternalFuncNode(self, value, value._external_name)
-            elif getattr(value, 'external', None) == 'C':
+            if getattr(value, 'external', None) == 'C':
                 node = ExternalFuncNode(self, value)
             else:
                 node = FuncImplNode(self, value)

Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py	Sat Nov 24 19:10:31 2007
@@ -6,18 +6,45 @@
 from pypy.objspace.flow.model import FunctionGraph
 from pypy.rpython.rmodel import inputconst
 from pypy.rpython.lltypesystem import lltype
-from pypy.translator.llvm.buildllvm import llvm_gcc_version
 from pypy.tool.udir import udir
 
-support_functions = [
-    "@LLVM_RPython_StartupCode",
-    ]
+def get_c_cpath():
+    from pypy.translator.c import genc
+    return os.path.dirname(genc.__file__)
+
+def get_llvm_cpath():
+    return os.path.join(os.path.dirname(__file__), "module")
 
 def get_module_file(name):
     return os.path.join(get_llvm_cpath(), name)
 
-def get_ll(ccode, function_names, default_cconv, c_include_dirs):
-    function_names += support_functions
+def get_incdirs(c_include_dirs):
+    import distutils.sysconfig
+
+    includes = tuple(c_include_dirs) + ("/sw/include",
+                distutils.sysconfig.EXEC_PREFIX + "/include", 
+                distutils.sysconfig.EXEC_PREFIX + "/include/gc",
+                distutils.sysconfig.get_python_inc(),
+                get_c_cpath(),
+                get_llvm_cpath())
+
+    includestr = ""
+    for ii in includes:
+        includestr += "-I %s " % ii
+    return includestr
+
+# call entrypoint needs to be fastcc
+# call boehm finalizers need to be fastcc
+
+def generate_ll(ccode, default_cconv, c_include_dirs, call_funcnames=[]):
+
+    call_funcnames += ['@LLVM_RPython_StartupCode']
+    define_funcnames = ['@pypy_malloc',
+                        '@pypy_malloc_atomic',
+                        '@pypy_gc__collect',
+                        '@pypy_register_finalizer']
+    declare_funcnames = ['@LLVM_RPython_StartupCode']
+
     filename = str(udir.join("ccode.c"))
     f = open(filename, "w")
     f.write(ccode)
@@ -25,13 +52,8 @@
 
     plain = filename[:-2]
     includes = get_incdirs(c_include_dirs)
-    if llvm_gcc_version() < 4.0:
-        emit_llvm = ''
-    else:
-        emit_llvm = '-emit-llvm -O0'
-        
-    cmd = "llvm-gcc %s %s -S %s.c -o %s.ll 2>&1" % (
-        includes, emit_llvm, plain, plain)
+    cmd = "llvm-gcc -emit-llvm -O0 -S %s %s.c -o %s.ll 2>&1" % (
+        includes, plain, plain)
 
     if os.system(cmd) != 0:
         raise Exception("Failed to run '%s'" % cmd)
@@ -39,10 +61,10 @@
     llcode = open(plain + '.ll').read()
 
     # strip lines
-    ll_lines = []
-    funcnames = dict([(k, True) for k in function_names])
+    lines = []
 
-    # strip declares that are in funcnames
+    calltag, declaretag, definetag = 'call ', 'declare ', 'define '
+    
     for line in llcode.split('\n'):
 
         # get rid of any of the structs that llvm-gcc introduces to struct types
@@ -54,102 +76,62 @@
             line = line[:comment]
         line = line.rstrip()
 
-        # find function names, declare them with the default calling convertion
-        #if '(' in  line and line[-1:] == '{':
-        #   returntype, s = line.split(' ', 1)
-        #   funcname  , s = s.split('(', 1)
-        #   funcnames[funcname] = True
-        #   if line.find("internal") == -1:
-        #        if funcname not in ["@main", "@ctypes_RPython_StartupCode"]:
-        #            internal = 'internal '
-        #            line = '%s%s %s' % (internal, default_cconv, line,)
-        ll_lines.append(line)
-
-    # patch calls to function that we just declared with different cconv
-    ll_lines2, calltag, declaretag, definetag = [], 'call ', 'declare ', 'define ' 
-    for line in ll_lines:
+        # patch calls (upgrade to default_cconv)
         i = line.find(calltag)
         if i >= 0:
-            cconv = 'ccc'
-            for funcname in funcnames.iterkeys():
+            for funcname in call_funcnames:
                 if line.find(funcname) >= 0:
-                    cconv = default_cconv
+                    line = "%scall %s %s" % (line[:i], default_cconv, line[i+len(calltag):])
                     break
-            line = "%scall %s %s" % (line[:i], cconv, line[i+len(calltag):])
+
         if line[:len(declaretag)] == declaretag:
-            cconv = 'ccc'
-            for funcname in funcnames.keys():
-                if line.find(funcname) >= 0:
-                    cconv = default_cconv
+            xline = line[len(declaretag):] 
+            for funcname in declare_funcnames: 
+                if xline.find(funcname) != -1:
+                    line = "declare %s %s %s" % (internal, default_cconv, xline)
                     break
-            line = "declare %s %s" % (cconv, line[len(declaretag):])
+                    
         if line[:len(definetag)] == definetag:
-            line = line.replace("internal ", "")
-            cconv = 'ccc'
-            for funcname in funcnames.keys():
-                if line.find(funcname) >= 0:
-                    cconv = default_cconv
+            xline = line[len(definetag):] 
+            internal = ''
+            if xline.startswith('internal '):
+                internal = 'internal '
+                xline = xline.replace('internal ', '')
+
+            for funcname in define_funcnames: 
+                if xline.find(funcname) != -1:
+                    line = "define %s %s %s" % (internal, default_cconv, xline)
                     break
-            line = "define %s %s" % (cconv, line[len(definetag):])
-        ll_lines2.append(line)
 
-    ll_lines2.append("declare ccc void @abort()")
-    return'\n'.join(ll_lines2)
+        lines.append(line)
 
-def get_c_cpath():
-    from pypy.translator.c import genc
-    return os.path.dirname(genc.__file__)
-
-def get_llvm_cpath():
-    return os.path.join(os.path.dirname(__file__), "module")
+    lines.append("declare ccc void @abort()")
+    return'\n'.join(lines)
 
-def get_incdirs(c_include_dirs):
-
-    import distutils.sysconfig
-
-    includes = tuple(c_include_dirs) + ("/sw/include",
-                distutils.sysconfig.EXEC_PREFIX + "/include", 
-                distutils.sysconfig.EXEC_PREFIX + "/include/gc",
-                distutils.sysconfig.get_python_inc(),
-                get_c_cpath(),
-                get_llvm_cpath(),)
-
-    includestr = ""
-    for ii in includes:
-        includestr += "-I %s " % ii
-    return includestr
-
-def generate_llfile(db, entrynode, c_include_dirs, c_includes, c_sources, standalone, default_cconv):
+def generate_c(db, entrynode, c_includes, c_sources, standalone):
     ccode = []
-    function_names = []
         
-    def predeclarefn(c_name, llname):
-        function_names.append(llname)
-        assert llname[0] == "@"
-        llname = llname[1:]
-        assert '\n' not in llname
-        ccode.append('#define\t%s\t%s\n' % (c_name, llname))
-
     if standalone:
-        predeclarefn("__ENTRY_POINT__", entrynode.get_ref())
-        ccode.append('#define ENTRY_POINT_DEFINED 1\n\n')
+        ccode.append('#define __ENTRY_POINT__ %s' % entrynode.get_ref()[1:])
+        ccode.append('#define ENTRY_POINT_DEFINED 1')
 
     # include python.h early
-    ccode.append('#include <Python.h>\n')
+    ccode.append('#include <Python.h>')
 
     # ask gcpolicy for any code needed
-    ccode.append('%s\n' % db.gcpolicy.genextern_code())
+    ccode.append('%s' % db.gcpolicy.genextern_code())
 
     # ask rffi for includes/source
     for c_include in c_includes:
-        ccode.append('#include <%s>\n' % c_include)
+        ccode.append('#include <%s>' % c_include)
         
+    ccode.append('')
+
     for c_source in c_sources:
-        ccode.append('\n')
-        ccode.append(c_source + '\n') 
-    ccode.append('\n')
+        ccode.append(c_source) 
+
+    ccode.append('')
 
     # append our source file
     ccode.append(open(get_module_file('genexterns.c')).read())
-    llcode = get_ll("".join(ccode), function_names, default_cconv, c_include_dirs)
-    return llcode
+    return "\n".join(ccode)

Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/extfuncnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/extfuncnode.py	Sat Nov 24 19:10:31 2007
@@ -39,5 +39,5 @@
         return "%s %s(%s)" % (rettype, self.ref, ", ".join(argtypes))
 
     def writedecl(self, codewriter):
-        codewriter.declare(self.getdecl())
+        codewriter.declare(self.getdecl(), cconv="ccc")
 

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Sat Nov 24 19:10:31 2007
@@ -12,7 +12,7 @@
 from pypy.translator.llvm import extfuncnode
 from pypy.translator.llvm.module.support import extfunctions
 from pypy.translator.llvm.node import Node
-from pypy.translator.llvm.externs2ll import generate_llfile
+from pypy.translator.llvm.externs2ll import generate_c, generate_ll
 from pypy.translator.llvm.gc import GcPolicy
 from pypy.translator.llvm.log import log
 from pypy.rlib.nonconst import NonConstant
@@ -198,14 +198,9 @@
             for source in sources:
                 c_sources[source] = True
 
-        self.llcode = generate_llfile(self.db,
-                                      self.entrynode,
-                                      c_include_dirs,
-                                      c_includes,
-                                      c_sources,
-                                      self.standalone, 
-                                      codewriter.cconv)
-
+        ccode = generate_c(self.db, self.entrynode, c_includes, c_sources, self.standalone)
+        self.llcode = generate_ll(ccode, codewriter.cconv, c_include_dirs)
+        
     def create_codewriter(self):
         # prevent running the same function twice in a test
         filename = udir.join(self.entry_name).new(ext='.ll')

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Sat Nov 24 19:10:31 2007
@@ -295,8 +295,23 @@
                                  opr.argrefs[0], "null")
 
     def direct_call(self, opr):
+        cconv = None
+
+        # XXX aargh - more illegal fishing
+        # XXX sort this out later...
+        arg = opr.op.args[0]
+        from pypy.objspace.flow.model import Constant
+        if isinstance(arg, Constant):
+            T = arg.concretetype.TO
+            assert isinstance(T, lltype.FuncType)
+            value = opr.op.args[0].value._obj        
+            if getattr(value, 'external', None) == 'C':
+                cconv = 'ccc'
+            
+        # if we are external node - should use standard calling conventions
         self.codewriter.call(opr.retref, opr.rettype, opr.argrefs[0],
-                             opr.argtypes[1:], opr.argrefs[1:])
+                             opr.argtypes[1:], opr.argrefs[1:], cconv=cconv)
+
     # the following works since the extra arguments that indirect_call has
     # is of type Void, which is removed by direct_call
     indirect_call = direct_call



More information about the Pypy-commit mailing list