[pypy-svn] r13589 - in pypy/dist/pypy/translator/llvm2: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Jun 18 21:51:54 CEST 2005
Author: cfbolz
Date: Sat Jun 18 21:51:54 2005
New Revision: 13589
Modified:
pypy/dist/pypy/translator/llvm2/cfgtransform.py
pypy/dist/pypy/translator/llvm2/codewriter.py
pypy/dist/pypy/translator/llvm2/database.py
pypy/dist/pypy/translator/llvm2/funcnode.py
pypy/dist/pypy/translator/llvm2/genllvm.py
pypy/dist/pypy/translator/llvm2/pyxwrapper.py
pypy/dist/pypy/translator/llvm2/test/llvmsnippet.py
pypy/dist/pypy/translator/llvm2/test/test_genllvm.py
Log:
(cfbolz, hpk)
made directcalls (recursive and non-recursive) work.
the setup() phase for FunctionNodes now traverses
the graph and adds any pending nodes so that
references can be used without having looked
at the function.
improved logging and code output
added a cfg transformation to remove same_as operations
(only tested implicitely)
Modified: pypy/dist/pypy/translator/llvm2/cfgtransform.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/cfgtransform.py (original)
+++ pypy/dist/pypy/translator/llvm2/cfgtransform.py Sat Jun 18 21:51:54 2005
@@ -1,4 +1,6 @@
from pypy.objspace.flow.model import traverse, Block, checkgraph
+from pypy.translator.unsimplify import remove_double_links
+
def remove_same_as(graph):
same_as_positions = []
@@ -32,3 +34,10 @@
node.operations[:] = filter(None, node.operations)
traverse(visit, graph)
checkgraph(graph)
+
+
+def prepare_graph(graph, translator):
+ remove_same_as(graph)
+ remove_double_links(translator, graph)
+ return graph
+
Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py (original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py Sat Jun 18 21:51:54 2005
@@ -12,10 +12,10 @@
log(line)
def indent(self, line):
- self.append(" " + line)
+ self.append(" " + line)
def label(self, name):
- self.append("%s:" % name)
+ self.append(" %s:" % name)
def declare(self, decl):
self.append("declare %s" %(decl,))
@@ -47,5 +47,10 @@
def binaryop(self, name, targetvar, type_, ref1, ref2):
self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2))
+ def call(self, targetvar, returntype, functionref, argrefs, argtypes):
+ arglist = ["%s %s" % item for item in zip(argtypes, argrefs)]
+ self.indent("%s = call %s %s(%s)" % (targetvar, returntype, functionref,
+ ", ".join(arglist)))
+
def __str__(self):
return "\n".join(self._lines)
Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py (original)
+++ pypy/dist/pypy/translator/llvm2/database.py Sat Jun 18 21:51:54 2005
@@ -2,8 +2,6 @@
from pypy.translator.llvm2.funcnode import FuncNode
from pypy.rpython import lltype
from pypy.objspace.flow.model import Block, Constant, Variable
-from pypy.translator.unsimplify import remove_double_links
-from pypy.translator.llvm2.cfgtransform import remove_same_as
log = log.database
@@ -13,27 +11,32 @@
class Database(object):
def __init__(self, translator):
self._translator = translator
- self.obj2node = {}
+ self.obj2node = {}
self._pendingsetup = []
- def getgraph(self, func):
- graph = self._translator.flowgraphs[func]
- remove_same_as(graph)
- remove_double_links(self._translator, graph)
- return graph
-
- def getnode(self, obj):
- assert hasattr(obj, 'func_code')
- try:
- return self.obj2node[obj]
- except KeyError:
- node = FuncNode(self, obj)
- self.obj2node[obj] = node
- log("add pending setup", node.ref)
- self._pendingsetup.append(node)
- return node
+ def prepare_ref(self, const_or_var):
+ if const_or_var in self.obj2node:
+ return
+ if isinstance(const_or_var, Constant):
+ if isinstance(const_or_var.concretetype, lltype.Primitive):
+ pass
+ else:
+ node = FuncNode(self, const_or_var)
+ self.obj2node[const_or_var] = node
+ log("added to pending nodes:", node)
+ self._pendingsetup.append(node)
+
+ def prepare_typeref(self, type_):
+ if not isinstance(type_, lltype.Primitive):
+ log.XXX("need to prepare typeref")
+
+ def prepare_arg(self, const_or_var):
+ log.prepare(const_or_var)
+ self.prepare_ref(const_or_var)
+ self.prepare_typeref(const_or_var.concretetype)
- def process(self):
+
+ def process(self):
if self._pendingsetup:
self._pendingsetup.pop().setup()
return bool(self._pendingsetup)
@@ -42,14 +45,12 @@
return self.obj2node.values()
def getref(self, arg):
- if isinstance(arg, Constant):
- if isinstance(arg.concretetype, lltype.Primitive):
- return str(arg.value).lower() #False --> false
- raise TypeError, "can't handle the Constant %s" % arg
+ if (isinstance(arg, Constant) and
+ isinstance(arg.concretetype, lltype.Primitive)):
+ return str(arg.value).lower() #False --> false
elif isinstance(arg, Variable):
return "%" + str(arg)
- else:
- raise TypeError, arg
+ return self.obj2node[arg].ref
def gettyperef(self, arg):
return PRIMITIVES_TO_LLVM[arg.concretetype]
Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py Sat Jun 18 21:51:54 2005
@@ -1,18 +1,33 @@
import py
-from pypy.objspace.flow.model import Block, Constant, Variable, flatten, mkentrymap
+from pypy.objspace.flow.model import Block, Constant, Variable, Link
+from pypy.objspace.flow.model import flatten, mkentrymap, traverse
+from pypy.translator.llvm2.cfgtransform import prepare_graph
from pypy.translator.llvm2.log import log
log = log.funcnode
class FuncNode(object):
_issetup = False
- def __init__(self, db, func):
+ def __init__(self, db, const_ptr_func):
self.db = db
- self.func = func
- self.ref = self.func.func_name
-
- def setup(self):
- self.graph = self.db.getgraph(self.func)
+ self.ref = "%" + const_ptr_func.value._obj._name
+ self.graph = prepare_graph(const_ptr_func.value._obj.graph,
+ db._translator)
+
+ def __str__(self):
+ return "<FuncNode ref=%s>" %(self.ref,)
+
+ def setup(self):
+ log("setup", self)
+ def visit(node):
+ if isinstance(node, Link):
+ map(self.db.prepare_arg, node.args)
+ elif isinstance(node, Block):
+ map(self.db.prepare_arg, node.inputargs)
+ for op in node.operations:
+ map(self.db.prepare_arg, op.args)
+ self.db.prepare_arg(op.result)
+ traverse(visit, self.graph)
self._issetup = True
def getdecl(self):
@@ -22,7 +37,7 @@
inputargs = self.db.multi_getref(startblock.inputargs)
inputargtypes = self.db.multi_gettyperef(startblock.inputargs)
returntype = self.db.gettyperef(self.graph.returnblock.inputargs[0])
- result = "%s %%%s" % (returntype, self.ref)
+ result = "%s %s" % (returntype, self.ref)
args = ["%s %s" % item for item in zip(inputargtypes, inputargs)]
result += "(%s)" % ", ".join(args)
return result
@@ -104,7 +119,7 @@
assert len(op.args) == 2
self.codewriter.binaryop(name,
self.db.getref(op.result),
- self.db.gettyperef(op.result),
+ self.db.gettyperef(op.args[0]),
self.db.getref(op.args[0]),
self.db.getref(op.args[1]))
def int_mul(self, op):
@@ -118,4 +133,16 @@
def int_sub(self, op):
self.binaryop('sub', op)
+
+ def int_eq(self, op):
+ self.binaryop('seteq', op)
+ def direct_call(self, op):
+ assert len(op.args) >= 1
+ targetvar = self.db.getref(op.result)
+ returntype = self.db.gettyperef(op.result)
+ functionref = self.db.getref(op.args[0])
+ argrefs = self.db.multi_getref(op.args[1:])
+ argtypes = self.db.multi_gettyperef(op.args[1:])
+ self.codewriter.call(targetvar, returntype, functionref, argrefs,
+ argtypes)
Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py Sat Jun 18 21:51:54 2005
@@ -1,7 +1,10 @@
from pypy.translator.llvm2 import build_llvm_module
from pypy.translator.llvm2.database import Database
from pypy.translator.llvm2.pyxwrapper import write_pyx_wrapper
-from pypy.translator.llvm2.log import log
+from pypy.translator.llvm2.log import log
+from pypy.objspace.flow.model import Constant
+from pypy.rpython.rmodel import inputconst, getfunctionptr
+from pypy.rpython import lltype
from pypy.tool.udir import udir
from pypy.translator.llvm2.codewriter import CodeWriter
@@ -10,13 +13,17 @@
func = translator.entrypoint
db = Database(translator)
- entrynode = db.getnode(func)
-
+ ptr = getfunctionptr(translator, func)
+ c = inputconst(lltype.typeOf(ptr), ptr)
+ db.prepare_ref(c)
+ assert c in db.obj2node
while db.process():
pass
-
+ entrynode = db.obj2node[c]
codewriter = CodeWriter()
dbobjects = db.getobjects()
+ log.debug(dbobjects)
+ log.debug(db.obj2node)
for node in dbobjects:
node.writedecl(codewriter)
for node in dbobjects:
Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/pyxwrapper.py (original)
+++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py Sat Jun 18 21:51:54 2005
@@ -11,7 +11,7 @@
funcgen.graph.returnblock.inputargs[0].concretetype]
inputargtypes = [PRIMITIVES_TO_C[arg.concretetype]
for arg in funcgen.graph.startblock.inputargs]
- result = "%s %s(%s)" % (returntype, funcgen.ref,
+ result = "%s %s(%s)" % (returntype, funcgen.ref.lstrip("%"),
", ".join(inputargtypes))
return result
lines = []
Modified: pypy/dist/pypy/translator/llvm2/test/llvmsnippet.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/llvmsnippet.py (original)
+++ pypy/dist/pypy/translator/llvm2/test/llvmsnippet.py Sat Jun 18 21:51:54 2005
@@ -1,27 +1,7 @@
#function snippets
-def simple2():
- return False
-def simple3(i):
- c = "Hello, Stars!"
- return c[i]
-
-def simple4():
- return 3 + simple1()
-
-
-def simple6():
- simple4()
- return 1
-
-def ackermann(n, m):
- if n == 0:
- return m + 1
- if m == 0:
- return ackermann(n - 1, 1)
- return ackermann(n - 1, ackermann(n, m - 1))
def calling1(m):
if m > 1:
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 Sat Jun 18 21:51:54 2005
@@ -11,6 +11,8 @@
from pypy.rpython.rtyper import RPythonTyper
py.log.setconsumer("genllvm", py.log.STDOUT)
+py.log.setconsumer("genllvm database prepare", None)
+
## def setup_module(mod):
## mod.llvm_found = is_on_path("llvm-as")
@@ -18,8 +20,7 @@
def compile_function(function, annotate):
t = Translator(function)
a = t.annotate(annotate)
- rt = RPythonTyper(a)
- rt.specialize()
+ t.specialize()
a.simplify()
return genllvm(t)
@@ -47,4 +48,24 @@
f = compile_function(ops, [int])
assert f(1) == 1
assert f(2) == 2
+
+def test_function_call():
+ def callee():
+ return 1
+ def caller():
+ return 3 + callee()
+ f = compile_function(caller, [])
+ assert f() == 4
+
+def test_recursive_call():
+ def call_ackermann(n, m):
+ return ackermann(n, m)
+ def ackermann(n, m):
+ if n == 0:
+ return m + 1
+ if m == 0:
+ return ackermann(n - 1, 1)
+ return ackermann(n - 1, ackermann(n, m - 1))
+ f = compile_function(call_ackermann, [int, int])
+ assert f(0, 2) == 3
More information about the Pypy-commit
mailing list