[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