[pypy-svn] r48583 - in pypy/dist/pypy/translator/llvm: . module
rxe at codespeak.net
rxe at codespeak.net
Sun Nov 11 23:06:23 CET 2007
Author: rxe
Date: Sun Nov 11 23:06:23 2007
New Revision: 48583
Removed:
pypy/dist/pypy/translator/llvm/module/protos.h
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/module/genexterns.c
pypy/dist/pypy/translator/llvm/module/support.py
Log:
kill a whole bunch of code which was mostly hacks to work with externs - most the tests still pass (ll_strtod_parts_to_float and ll_strtod_formatd will soon be implemented via rffi) we also dont rely on translator/c/extfunc.py anymore
Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py (original)
+++ pypy/dist/pypy/translator/llvm/database.py Sun Nov 11 23:06:23 2007
@@ -6,7 +6,7 @@
from pypy.translator.llvm.typedefnode import create_typedef_node
from pypy.translator.llvm.funcnode import FuncImplNode
-from pypy.translator.llvm.extfuncnode import ExternalFuncNode, SimplerExternalFuncNode
+from pypy.translator.llvm.extfuncnode import ExternalFuncNode
from pypy.translator.llvm.opaquenode import OpaqueNode, ExtOpaqueNode
from pypy.translator.llvm.structnode import StructNode, StructVarsizeNode, \
getindexhelper, FixedSizeArrayNode
@@ -65,12 +65,11 @@
node = None
if isinstance(type_, lltype.FuncType):
if getattr(value._callable, "suggested_primitive", False):
- node = ExternalFuncNode(self, value)
+ node = ExternalFuncNode(self, value, value._callable)
elif hasattr(value, '_external_name'):
node = ExternalFuncNode(self, value, value._external_name)
-
elif getattr(value, 'external', None) == 'C':
- node = SimplerExternalFuncNode(self, value)
+ 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 Sun Nov 11 23:06:23 2007
@@ -9,22 +9,66 @@
from pypy.translator.llvm.buildllvm import llvm_gcc_version
from pypy.tool.udir import udir
+from pypy.rpython.module import ll_stack
+from pypy.rpython.lltypesystem.module import ll_strtod
+
+ll_stack_too_big = """
+
+define internal ccc i1 @LL_stack_too_big_() {
+ %result = call ccc i32 @LL_stack_too_big()
+ %tmp = trunc i32 %result to i1
+ ret i1 %tmp
+}
+
+"""
+
+# table of functions hand-written in src/ll_*.h
+# Note about *.im_func: The annotator and the rtyper expect direct
+# references to functions, so we cannot insert classmethods here.
+
+EXTERNALS = {
+ ll_stack.ll_stack_unwind: 'LL_stack_unwind',
+ ll_stack.ll_stack_too_big: 'LL_stack_too_big_',
+ }
+
+
+math_functions = [
+ 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs',
+ 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh',
+ 'pow', 'atan2', 'fmod', 'ldexp', 'hypot'
+ ]
+import math
+for name in math_functions:
+ EXTERNALS['ll_math.ll_math_%s' % name] = 'LL_math_%s' % name
+
+def predeclare_stuff(c_db):
+ modules = {}
+ def module_name(c_name):
+ frags = c_name[3:].split('_')
+ if frags[0] == '':
+ return '_' + frags[1]
+ else:
+ return frags[0]
+
+ for func, funcobj in c_db.externalfuncs.items():
+ c_name = EXTERNALS[func]
+ # construct a define LL_NEED_<modname> to make it possible to isolate in-development externals and headers
+ modname = module_name(c_name)
+ if modname not in modules:
+ modules[modname] = True
+ yield 'LL_NEED_%s' % modname.upper(), 1
+ funcptr = funcobj._as_ptr()
+ yield c_name, funcptr
+
+ exctransformer = c_db.exctransformer
+ yield ('_rpyexc_occured_ptr', exctransformer._rpyexc_occured_ptr.value)
+ yield ('rpyexc_fetch_type_ptr', exctransformer.rpyexc_fetch_type_ptr.value)
+ yield ('rpyexc_clear_ptr', exctransformer.rpyexc_clear_ptr.value)
support_functions = [
- "@raisePyExc_IOError",
- "@raisePyExc_ValueError",
- "@raisePyExc_OverflowError",
- "@raisePyExc_ZeroDivisionError",
- "@raisePyExc_RuntimeError",
- "@raisePyExc_thread_error",
- "@RPyString_FromString",
- "@RPyString_AsString",
- "@RPyString_Size",
- "@RPyExceptionOccurred",
"@LLVM_RPython_StartupCode",
]
-
skip_lines = [
"%RPyString = type opaque",
"__main",
@@ -120,23 +164,21 @@
ll_lines2.append(line)
ll_lines2.append("declare ccc void @abort()")
+ return'\n'.join(ll_lines2)
- llcode = '\n'.join(ll_lines2)
- decl, impl = '', llcode
- #try:
- # decl, impl = llcode.split('implementation')
- #except:
- # raise Exception("Can't compile external function code (llcode.c)")
- return decl, impl
-
+def find_list_of_str(rtyper):
+ from pypy.rpython.lltypesystem import rlist
+ for r in rtyper.reprs.itervalues():
+ if isinstance(r, rlist.ListRepr) and r.item_repr is rstr.string_repr:
+ return r.lowleveltype.TO
+ return None
def setup_externs(c_db, db):
- rtyper = db.translator.rtyper
- from pypy.translator.c.extfunc import predeclare_all
-
# hacks to make predeclare_all work
- decls = list(predeclare_all(c_db, rtyper))
+ rtyper = db.translator.rtyper
+ decls = list(predeclare_stuff(c_db))
+
for c_name, obj in decls:
if isinstance(obj, lltype.LowLevelType):
db.prepare_type(obj)
@@ -197,30 +239,29 @@
predeclarefn("__ENTRY_POINT__", entrynode.get_ref())
ccode.append('#define ENTRY_POINT_DEFINED 1\n\n')
+ LL_stack_too_big_ = False
for c_name, obj in extern_decls:
if isinstance(obj, lltype.LowLevelType):
s = "#define %s struct %s\n%s;\n" % (c_name, c_name, c_name)
ccode.append(s)
+
elif isinstance(obj, FunctionGraph):
funcptr = db.translator.rtyper.getcallable(obj)
c = inputconst(lltype.typeOf(funcptr), funcptr)
predeclarefn(c_name, db.repr_arg(c))
+
elif isinstance(lltype.typeOf(obj), lltype.Ptr):
- if c_name.startswith("RPyExc_"):
- c_name = c_name[1:]
- ccode.append("void raise%s(char *);\n" % c_name)
- #else:
- # # XXX we really shouldnt do this
- # predeclarefn(c_name, db.obj2node[obj._obj].ref)
+ pass
+
elif type(c_name) is str and type(obj) is int:
+ if c_name == 'LL_NEED_STACK':
+ LL_stack_too_big_ = True
ccode.append("#define\t%s\t%d\n" % (c_name, obj))
+
else:
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')
@@ -238,4 +279,10 @@
# append our source file
ccode.append(open(get_module_file('genexterns.c')).read())
- return get_ll("".join(ccode), function_names, default_cconv)
+ llcode = get_ll("".join(ccode), function_names, default_cconv)
+
+ # XXX enormous temporary hack
+ if LL_stack_too_big_:
+ llcode += ll_stack_too_big
+
+ return llcode
Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/extfuncnode.py (original)
+++ pypy/dist/pypy/translator/llvm/extfuncnode.py Sun Nov 11 23:06:23 2007
@@ -1,33 +1,16 @@
from pypy.translator.llvm.node import FuncNode
-from pypy.translator.llvm.log import log
-from pypy.translator.c.extfunc import EXTERNALS
+from pypy.translator.llvm.externs2ll import EXTERNALS
from pypy.rpython.lltypesystem import lltype
-log = log.extfuncnode
-
-from sys import maxint
-
-class ExtFuncSig(object):
- def __init__(self, rettype, args):
- self.rettype = rettype
- self.args = args
-
-# signature of external functions differ from C's implementation
-ext_func_sigs = {
- "@LL_stack_too_big_" : ExtFuncSig("i32", None),
- }
-
-# XXX 64 bit is really broken since 2.x
-#if maxint != 2**31-1:
-# ext_func_sigs["@LL_math_ldexp"] = ExtFuncSig(None, [None, "int"])
-
-
-class SimplerExternalFuncNode(FuncNode):
-
- def __init__(self, db, value):
+class ExternalFuncNode(FuncNode):
+ def __init__(self, db, value, mapname=None):
+ if mapname is None:
+ name = value._name
+ else:
+ name = EXTERNALS[mapname]
self.db = db
self.value = value
- self.name = "@" + value._name
+ self.name = "@" + name
def external_c_source(self):
# return a list of unique includes and sources in C
@@ -58,132 +41,3 @@
def writedecl(self, codewriter):
codewriter.declare(self.getdecl())
-class ExternalFuncNode(FuncNode):
- prefix = '@'
-
- def __init__(self, db, value, extname=None):
- self.db = db
- self.value = value
- name = value._callable.__name__
-
- self.callable = value._callable
- if extname is not None:
- mapped_name = EXTERNALS[extname]
- else:
- mapped_name = EXTERNALS[self.callable]
-
- self.make_name(mapped_name)
- if ext_func_sigs.get(self.ref + '_', None):
- self.origref = self.ref
- self.name += "_"
-
- def setup(self):
- self.db.prepare_type(self.value._TYPE.RESULT)
- self.db.prepare_type_multi(self.value._TYPE._trueargs())
-
- def _get_wrapper(self):
- wrapper = ext_func_sigs.get(self.ref, None)
-
-# if wrapper is None and maxint != 2**31-1:
-# #log("ref=%s" % self.ref)
-# rettype, args = self.getdecl_parts()
-# conversions = False
-# if rettype == "long":
-# rettype = "int"
-# conversions = True
-# elif rettype == "ulong":
-# rettype = "uint"
-# conversions = True
-# else:
-# rettype = None
-# for i, a in enumerate(args):
-# if a == "long":
-# args[i] = "int"
-# conversions = True
-# elif a == "ulong":
-# args[i] = "uint"
-# conversions = True
-# else:
-# args[i] = None
-# if conversions:
-# wrapper = ExtFuncSig(rettype, args)
-# #log(" rettype=%s" % str(rettype))
-# #log(" args =%s" % str(args))
- return wrapper
-
- def getdecl_parts(self):
- T = self.value._TYPE
- rettype = self.db.repr_type(T.RESULT)
- argtypes = [self.db.repr_type(a) for a in T.ARGS if a is not lltype.Void]
- return rettype, argtypes
-
- def getdecl(self):
- rettype, argtypes = self.getdecl_parts()
- return "%s %s(%s)" % (rettype, self.ref, ", ".join(argtypes))
-
- def writedecl(self, codewriter):
- codewriter.declare(self.getdecl())
-
- def writeimpl(self, codewriter):
- wrapper = self._get_wrapper()
- if wrapper is None:
- return
-
- rettype, argtypes = self.getdecl_parts()
- argrefs = [self.db.repr_tmpvar() for ii in argtypes]
- arg_desription = ", ".join([
- "%s %s" % (typ_, name)
- for typ_, name in zip(argtypes, argrefs)])
- open_decl = "%s %s(%s)" % (rettype, self.ref, arg_desription)
- codewriter.openfunc(open_decl)
-
- returnval = self.db.repr_tmpvar()
-
- # call function with this
- expected_argrefs = []
- expected_argtypes = []
-
- # find out what the args/types should be
- if wrapper.args is not None:
- assert len(wrapper.args) == len(argtypes)
-
- for expected_typ, typ, ref in zip(wrapper.args,
- argtypes,
- argrefs):
- if expected_typ is not None:
-
- # cast to desired arg type
- expected_ref = self.db.repr_tmpvar()
- codewriter.cast(expected_ref, typ, ref, expected_typ)
-
- else:
- expected_ref = ref
- expected_typ = typ
-
- expected_argrefs.append(expected_ref)
- expected_argtypes.append(expected_typ)
- else:
- expected_argrefs = argrefs
- expected_argtypes = argtypes
-
- # find out what the return type should be
- expected_rettype = wrapper.rettype or rettype
-
- # call
- codewriter.call(returnval, expected_rettype, self.origref,
- expected_argtypes, expected_argrefs)
-
- if wrapper.rettype:
- # cast to desired return type
- tmpval = returnval
- returnval = self.db.repr_tmpvar()
- # XXX note we only have one case above - more will need
- # to specialize the cast
- codewriter.cast(returnval, wrapper.rettype,
- tmpval, rettype, 'trunc')
-
- codewriter.ret(rettype, returnval)
- codewriter.closefunc()
-
- def writeglobalconstants(self, codewriter):
- pass
Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py Sun Nov 11 23:06:23 2007
@@ -10,8 +10,7 @@
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, extfunctions_standalone, write_raise_exc
+from pypy.translator.llvm.module.support import extfunctions
from pypy.translator.llvm.node import Node
from pypy.translator.llvm.externs2ll import setup_externs, generate_llfile
from pypy.translator.llvm.gc import GcPolicy
@@ -32,19 +31,41 @@
self.config = translator.config
def gen_source(self, func):
- self._checkpoint()
+ self._checkpoint("before gen source")
codewriter = self.setup(func)
- # write top part of llvm file
- self.write_headers(codewriter)
+ codewriter.header_comment("Extern code")
+ codewriter.write_lines(self.llcode)
- codewriter.startimpl()
+ codewriter.header_comment("Type declarations")
+ for typ_decl in self.db.gettypedefnodes():
+ typ_decl.writetypedef(codewriter)
- # write bottom part of llvm file
- self.write_implementations(codewriter)
+ codewriter.header_comment("Function prototypes")
+ for node in self.db.getnodes():
+ if hasattr(node, 'writedecl'):
+ node.writedecl(codewriter)
+
+ codewriter.header_comment("Prebuilt constants")
+ for node in self.db.getnodes():
+ # XXX tmp
+ if hasattr(node, "writeglobalconstants"):
+ node.writeglobalconstants(codewriter)
+
+ self._checkpoint("before definitions")
+
+ codewriter.header_comment('Suppport definitions')
+ codewriter.write_lines(extfunctions, patch=True)
+
+ codewriter.header_comment('Startup definition')
+ self.write_startup_impl(codewriter)
+
+ codewriter.header_comment("Function definitions")
+ for node in self.db.getnodes():
+ if hasattr(node, 'writeimpl'):
+ node.writeimpl(codewriter)
- # write entry point if there is one
codewriter.comment("End of file")
codewriter.close()
self._checkpoint('done')
@@ -98,65 +119,7 @@
self._checkpoint('setup_externs')
return codewriter
-
- def write_headers(self, codewriter):
- # write external function headers
- codewriter.header_comment('External Function Headers')
- codewriter.write_lines(self.llexterns_header)
-
- codewriter.header_comment("Type Declarations")
-
- # write extern type declarations
- self.write_extern_decls(codewriter)
- self._checkpoint('write externs type declarations')
-
- # write node type declarations
- for typ_decl in self.db.gettypedefnodes():
- typ_decl.writetypedef(codewriter)
- self._checkpoint('write data type declarations')
-
- codewriter.header_comment("Global Data")
-
- # write pbcs
- for node in self.db.getnodes():
- # XXX tmp
- if hasattr(node, "writeglobalconstants"):
- node.writeglobalconstants(codewriter)
- self._checkpoint('write global constants')
-
- codewriter.header_comment("Function Prototypes")
-
- # write external protos
- codewriter.write_lines(extdeclarations, patch=True)
-
- # write node protos
- for node in self.db.getnodes():
- if hasattr(node, 'writedecl'):
- node.writedecl(codewriter)
-
- self._checkpoint('write function prototypes')
-
- def write_implementations(self, codewriter):
- codewriter.header_comment("Function Implementation")
-
- # write external function implementations
- codewriter.header_comment('External Function Implementation')
- codewriter.write_lines(self.llexterns_functions)
- codewriter.write_lines(extfunctions, patch=True)
- if self.standalone:
- codewriter.write_lines(extfunctions_standalone, patch=True)
- self.write_extern_impls(codewriter)
- self.write_setup_impl(codewriter)
-
- self._checkpoint('write support implentations')
-
- # write all node implementations
- for node in self.db.getnodes():
- if hasattr(node, 'writeimpl'):
- node.writeimpl(codewriter)
-
- self._checkpoint('write node implementations')
-
+
def get_entry_point(self, func):
assert func is not None
self.entrypoint = func
@@ -191,14 +154,13 @@
for source in sources:
c_sources[source] = True
- self.llexterns_header, self.llexterns_functions = \
- generate_llfile(self.db,
- self.extern_decls,
- self.entrynode,
- c_includes,
- c_sources,
- self.standalone,
- codewriter.cconv)
+ self.llcode = generate_llfile(self.db,
+ self.extern_decls,
+ self.entrynode,
+ c_includes,
+ c_sources,
+ self.standalone,
+ codewriter.cconv)
def create_codewriter(self):
# prevent running the same function twice in a test
@@ -208,24 +170,8 @@
return CodeWriter(f, self.db), filename
else:
return CodeWriter(f, self.db, cconv='ccc', linkage=''), filename
-
- def write_extern_decls(self, codewriter):
- for c_name, obj in self.extern_decls:
- if isinstance(obj, lltype.LowLevelType):
- if isinstance(obj, lltype.Ptr):
- obj = obj.TO
-
- l = "%%%s = type %s" % (c_name, self.db.repr_type(obj))
- codewriter.write_lines(l)
- def write_extern_impls(self, codewriter):
- for c_name, obj in self.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 write_setup_impl(self, codewriter):
+ def write_startup_impl(self, codewriter):
open_decl = "i8* @LLVM_RPython_StartupCode()"
codewriter.openfunc(open_decl)
for node in self.db.getnodes():
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 Sun Nov 11 23:06:23 2007
@@ -1,11 +1,24 @@
+#include <stdlib.h>
-// append some genc files here manually from python
-#ifdef _RPyListOfString_New /* :-( */
-# define HAVE_RPY_LIST_OF_STRING
-#endif
+char *LLVM_RPython_StartupCode(void);
+
+#define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg);
+
+// XXX abort() this is just to make tests pass. actually it is a million times
+// better than it was since it used to basically be a nooop.
+
+// all of these will go away at some point
+
+#define FAKE_ERROR(name) \
+ int raisePyExc_##name(char *x) { \
+ abort(); \
+ }
#ifdef LL_NEED_MATH
+ FAKE_ERROR(OverflowError);
+ FAKE_ERROR(ValueError);
#include "c/src/ll_math.h"
+
#endif
#ifdef LL_NEED_STRTOD
@@ -13,10 +26,12 @@
#endif
#ifdef LL_NEED_STACK
+ FAKE_ERROR(RuntimeError);
#include "c/src/thread.h"
#include "c/src/stack.h"
#endif
+
// raw malloc code
char *raw_malloc(long size) {
return malloc(size);
@@ -34,10 +49,7 @@
memset(ptr, 0, size);
}
-char *LLVM_RPython_StartupCode();
-
char *RPython_StartupCode() {
-
// is there any garbage collection / memory management initialisation
__GC_STARTUP_CODE__
@@ -50,6 +62,7 @@
int main(int argc, char *argv[])
{
+ XXX
char *errmsg;
int i, exitcode;
RPyListOfString *list;
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 Sun Nov 11 23:06:23 2007
@@ -1,31 +1,4 @@
-extdeclarations = """
-declare ccc i32 @strlen(i8*)
-"""
-
extfunctions = """
-define internal CC %RPyString* @RPyString_FromString(i8* %s) {
- %len = call ccc i32 @strlen(i8* %s)
- %rpy = call CC %RPyString* @pypy_RPyString_New__Signed(i32 %len)
- %rpystrptr = getelementptr %RPyString* %rpy, i32 0, i32 1, i32 1
- %rpystr = bitcast [0 x i8]* %rpystrptr to i8*
-
- call ccc void @llvm.memcpyPOSTFIX(i8* %rpystr, i8* %s, WORD %len, WORD 0)
-
- ret %RPyString* %rpy
-}
-
-define internal CC i8* @RPyString_AsString(%RPyString* %structstring) {
- %source1ptr = getelementptr %RPyString* %structstring, i32 0, i32 1, i32 1
- %source1 = bitcast [0 x i8]* %source1ptr to i8*
- ret i8* %source1
-}
-
-define internal CC WORD @RPyString_Size(%RPyString* %structstring) {
- %sizeptr = getelementptr %RPyString* %structstring, i32 0, i32 1, i32 0
- %size = load WORD* %sizeptr
- ret WORD %size
-}
-
define internal CC double @pypyop_float_abs(double %x) {
block0:
%cond1 = fcmp ugt double %x, 0.0
@@ -61,28 +34,5 @@
%result = phi i64 [%x, %block0], [%x2, %block1]
ret i64 %result
}
-
"""
-extfunctions_standalone = """
-"""
-from sys import maxint
-if maxint != 2**31-1:
- extfunctions_standalone += """
-internal CC int %pypy_entry_point(%RPyListOfString* %argv) {
- %result = call CC long %pypy_entry_point(%RPyListOfString* %argv)
- %tmp = cast long %result to int
- ret int %tmp
-}
-
-"""
-
-def write_raise_exc(c_name, exc_repr, codewriter):
- l = """
-define internal CC void @raise%s(i8* %%msg) {
- ;%%exception_value = cast %s to %%RPYTHON_EXCEPTION*
- ret void
-}
-""" % (c_name, exc_repr)
- codewriter.write_lines(l, patch=True)
-
More information about the Pypy-commit
mailing list