[pypy-svn] r14361 - in pypy/dist/pypy: rpython translator/llvm2 translator/llvm2/test
rxe at codespeak.net
rxe at codespeak.net
Wed Jul 6 22:09:43 CEST 2005
Author: rxe
Date: Wed Jul 6 22:09:40 2005
New Revision: 14361
Modified:
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/translator/llvm2/database.py
pypy/dist/pypy/translator/llvm2/extfunction.py
pypy/dist/pypy/translator/llvm2/funcnode.py
pypy/dist/pypy/translator/llvm2/test/test_genllvm.py
Log:
(ericvrp, rxe) an initial stab at external functions in llvm.
Added external func node which can translate simple cases of calling external
functions. Provides some functionality for special cases.
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Wed Jul 6 22:09:40 2005
@@ -14,7 +14,7 @@
self.backend_functiontemplate = backend_functiontemplate
table = {}
-def declare(func, annotation, ll_function, ll_annotable=True, backend_functiontemplate=None):
+def declare(func, annotation, ll_function, ll_annotable=False, backend_functiontemplate=None):
# annotation can be a function computing the annotation
# or a simple python type from which an annotation will be constructed
global table
@@ -58,13 +58,15 @@
def ll_time_sleep(t):
time.sleep(t)
+nonefactory = lambda a: None
+
# external function declarations
-declare(os.open , int , ll_os_open , True ) #this is not annotatable actually, but llvm has an issue
-declare(os.read , str , ll_os_read , True )
-declare(os.write , int , ll_os_write , True )
-declare(os.close , lambda a: None, ll_os_close , True , 'C:close' )
-declare(os.getcwd , str , ll_os_getcwd , True )
-declare(os.dup , int , ll_os_dup , True , 'C:dup' )
-declare(time.time , float , ll_time_time , True )
-declare(time.clock, float , ll_time_clock, True )
-declare(time.sleep, lambda a: None, ll_time_sleep, True )
+declare(os.open , int , ll_os_open)
+declare(os.read , str , ll_os_read)
+declare(os.write , int , ll_os_write)
+declare(os.close , nonefactory, ll_os_close)
+declare(os.getcwd , str , ll_os_getcwd)
+declare(os.dup , int , ll_os_dup)
+declare(time.time , float , ll_time_time)
+declare(time.clock, float , ll_time_clock)
+declare(time.sleep, nonefactory, ll_time_sleep)
Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py (original)
+++ pypy/dist/pypy/translator/llvm2/database.py Wed Jul 6 22:09:40 2005
@@ -1,5 +1,5 @@
from pypy.translator.llvm2.log import log
-from pypy.translator.llvm2.funcnode import FuncNode, FuncTypeNode
+from pypy.translator.llvm2.funcnode import ExternalFuncNode, FuncNode, FuncTypeNode
from pypy.translator.llvm2.structnode import StructNode, StructVarsizeNode, \
StructTypeNode, StructVarsizeTypeNode
from pypy.translator.llvm2.arraynode import ArrayNode, ArrayTypeNode
@@ -86,10 +86,8 @@
type_ = lltype.typeOf(value)
node = None
if isinstance(type_, lltype.FuncType):
-
- if value._callable \
- and not hasattr(value, 'graph'):
- log('EXTERNAL FUNCTION' + str(dir(value)))
+ if ((not hasattr(value, "graph")) or value.graph is None) and value._callable:
+ node = ExternalFuncNode(self, value)
else:
node = FuncNode(self, value)
@@ -126,6 +124,7 @@
assert isinstance(ct, lltype.Ptr), "Preperation of non primitive and non pointer"
value = const_or_var.value._obj
+
self.addpending(const_or_var, self.create_constant_node(value))
else:
log.prepare(const_or_var, type(const_or_var))
Modified: pypy/dist/pypy/translator/llvm2/extfunction.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/extfunction.py (original)
+++ pypy/dist/pypy/translator/llvm2/extfunction.py Wed Jul 6 22:09:40 2005
@@ -1,4 +1,5 @@
-extdeclarations = """; External declarations
+extdeclarations = """; External declarations
+
; XXX these int's might need to be long's on 64 bit CPU's :(
@@ -7,6 +8,7 @@
declare void %sleep(int)
; End of external declarations
+
"""
extfunctions = """; External functions (will be inlined by LLVM)
@@ -24,7 +26,7 @@
ret double %v2
}
-void %ll_time_sleep__Float(double %f) {
+void %ll_time_sleep(double %f) {
%i = cast double %f to int
call void %sleep(int %i)
ret void
Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py Wed Jul 6 22:09:40 2005
@@ -32,8 +32,7 @@
decl = "%s type %s (%s)*" % (self.ref, returntype,
", ".join(inputargtypes))
codewriter.funcdef(self.ref, returntype, inputargtypes)
-
-
+
class FuncNode(LLVMNode):
_issetup = False
@@ -61,12 +60,16 @@
assert self.graph, "cannot traverse"
traverse(visit, self.graph)
self._issetup = True
+
# ______________________________________________________________________
# main entry points from genllvm
def writedecl(self, codewriter):
codewriter.declare(self.getdecl())
def writeimpl(self, codewriter):
+
+ # XXX Code checks for when the rpython extfunctable has set the annotable
+ # flag to True?????
_callable = self.value._callable
for func, extfuncinfo in extfunctable.iteritems(): # precompute a dict?
if _callable is extfuncinfo.ll_function:
@@ -153,6 +156,88 @@
else:
codewriter.ret_void()
+
+class ExternalFuncNode(LLVMNode):
+
+ fnmapping = {
+ "%ll_os_dup": "%dup",
+ "%ll_os_open": "%open",
+ "%ll_os_close": "%close",
+ #"%": ("int" "%open", "sbyte*", "int"),
+ #"%ll_os_write": ("int" "%write", "int", "sbyte*", "int"),
+ }
+
+ ignoreset = "%ll_time_time %ll_time_clock %ll_time_sleep".split()
+
+ def __init__(self, db, value):
+ self.db = db
+ self.value = value
+ self.ref = "%" + value._name
+
+ def setup(self):
+ self._issetup = True
+
+ def getdecl(self):
+ T = self.value._TYPE
+ args = [self.db.repr_arg_type(a) for a in T.ARGS]
+ decl = "%s %s(%s)" % (self.db.repr_arg_type(T.RESULT),
+ self.ref,
+ ", ".join(args))
+ return decl
+
+ def getcdecl(self):
+ #XXX Mapping
+ T = self.value._TYPE
+ args = [self.db.repr_arg_type(a) for a in T.ARGS]
+ decl = "%s %s(%s)" % (self.db.repr_arg_type(T.RESULT),
+ self.fnmapping[self.ref],
+ ", ".join(args))
+ return decl
+
+ # ______________________________________________________________________
+ # main entry points from genllvm
+ def writedecl(self, codewriter):
+ codewriter.declare(self.getdecl())
+
+ if self.ref not in self.ignoreset:
+ codewriter.declare(self.getcdecl())
+
+ def writeimpl(self, codewriter):
+ if self.ref in self.ignoreset:
+ return
+
+ T = self.value._TYPE
+ args = ["%s %%a%s" % (self.db.repr_arg_type(a), c)
+ for c, a in enumerate(T.ARGS)]
+
+ decl = "%s %s(%s)" % (self.db.repr_arg_type(T.RESULT),
+ self.ref,
+ ", ".join(args))
+
+ codewriter.openfunc(decl)
+
+ # go thru and map argsXXX
+ argrefs = ["%%a%s" % c for c in range(len(T.ARGS))]
+ argtypes = [self.db.repr_arg_type(a) for a in T.ARGS]
+
+ # get return type (mapped perhaps)
+ resulttype = self.db.repr_arg_type(T.RESULT)
+
+ # get function name
+ fnname = self.fnmapping[self.ref]
+
+ # call
+
+ # map resulttype ??? XXX
+ if resulttype != "void":
+ codewriter.call("%res", resulttype, fnname, argrefs, argtypes)
+ codewriter.ret(resulttype, "%res")
+ else:
+ codewriter.call_void(fnname, argrefs, argtypes)
+ codewriter.ret_void()
+
+ codewriter.closefunc()
+
class OpWriter(object):
binary_operations = {'int_mul': 'mul',
'int_add': 'add',
Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Wed Jul 6 22:09:40 2005
@@ -41,9 +41,21 @@
import os
def fn():
return os.dup(0)
- f = compile_function(fn, [], view=False)
+ f = compile_function(fn, [])
assert os.path.sameopenfile(f(), fn())
+def test_external_file_fns():
+ import os
+ def external_file_fns(intname, flags):
+ name = str(intname)
+ fd = os.open(name, flags)
+ #os.write(fd, name)
+ os.close(fd)
+ return fd
+
+ f = compile_function(external_file_fns, [int, int])
+ assert isinstance(f(1209319, 64), int)
+
def DONTtest_external_function_ll_os_getcmd():
import os
def fn():
More information about the Pypy-commit
mailing list