[pypy-svn] r14702 - in pypy/dist/pypy/translator/llvm2: . test
rxe at codespeak.net
rxe at codespeak.net
Fri Jul 15 17:01:13 CEST 2005
Author: rxe
Date: Fri Jul 15 17:01:09 2005
New Revision: 14702
Added:
pypy/dist/pypy/translator/llvm2/opaquenode.py
Modified:
pypy/dist/pypy/translator/llvm2/arraynode.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/node.py
pypy/dist/pypy/translator/llvm2/structnode.py
pypy/dist/pypy/translator/llvm2/test/test_lltype.py
Log:
* add dummy opaque nodes.
* get rid of hack in StructVarsizeNode where we were creating multiple nodes
for the last entry in the struct.
* refactored out database to just use obj2node and _pendingsetup attributes
again.
Will write to pypy-dev with status update later today.
Modified: pypy/dist/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/arraynode.py (original)
+++ pypy/dist/pypy/translator/llvm2/arraynode.py Fri Jul 15 17:01:09 2005
@@ -1,7 +1,7 @@
import py
from pypy.rpython import lltype
from pypy.translator.llvm2.log import log
-from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2.node import LLVMNode, ConstantLLVMNode
from pypy.translator.llvm2 import varsize
import itertools
log = log.structnode
@@ -51,7 +51,7 @@
self.constructor_decl,
fromtype)
-class ArrayNode(LLVMNode):
+class ArrayNode(ConstantLLVMNode):
""" An arraynode. Elements can be
a primitive,
a struct,
@@ -71,24 +71,24 @@
def setup(self):
if isinstance(self.arraytype, lltype.Ptr):
for item in self.value.items:
- self.db.addptrvalue(item)
+ self.db.prepare_ptr(item)
# set castref (note we must ensure that types are "setup" before we can
# get typeval)
typeval = self.db.repr_arg_type(lltype.typeOf(self.value))
- self.castref = "cast (%s* %s to %s*)" % (self.get_typestr(),
+ self.castref = "cast (%s* %s to %s*)" % (self.get_typerepr(),
self.ref,
typeval)
self._issetup = True
- def get_typestr(self):
+ def get_typerepr(self):
items = self.value.items
arraylen = len(items)
typeval = self.db.repr_arg_type(self.arraytype)
return "{ int, [%s x %s] }" % (arraylen, typeval)
def castfrom(self):
- return "%s*" % self.get_typestr()
+ return "%s*" % self.get_typerepr()
def constantvalue(self):
""" Returns the constant representation for this node. """
@@ -96,13 +96,13 @@
arraylen = len(items)
typeval = self.db.repr_arg_type(self.arraytype)
- arrayvalues = [self.db.reprs_constant(v) for v in items]
+ arrayvalues = [self.db.repr_constant(v)[1] for v in items]
value = "int %s, [%s x %s] [ %s ]" % (arraylen,
arraylen,
typeval,
", ".join(arrayvalues))
- return "%s {%s}" % (self.get_typestr(), value)
+ return "%s {%s}" % (self.get_typerepr(), value)
# ______________________________________________________________________
# entry points from genllvm
Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py (original)
+++ pypy/dist/pypy/translator/llvm2/database.py Fri Jul 15 17:01:09 2005
@@ -3,6 +3,8 @@
from pypy.translator.llvm2.structnode import StructNode, StructVarsizeNode, \
StructTypeNode, StructVarsizeTypeNode
from pypy.translator.llvm2.arraynode import ArrayNode, ArrayTypeNode
+from pypy.translator.llvm2.opaquenode import OpaqueNode, OpaqueTypeNode
+from pypy.translator.llvm2.node import ConstantLLVMNode
from pypy.rpython import lltype
from pypy.objspace.flow.model import Block, Constant, Variable
@@ -30,10 +32,10 @@
def dump(self):
for x,y in self._dict.items():
print x, y
- def _get(self, key):
+ def _get(self, key):
if isinstance(key, Constant):
- if isinstance(key.value, lltype._ptr):
- key = key.value._obj
+ if isinstance(key.value, lltype._ptr):
+ key = key.value._obj
return key
def __getitem__(self, key):
key = self._get(key)
@@ -58,7 +60,7 @@
elif type_ is lltype.Char:
repr = str(ord(value))
elif type_ is lltype.UniChar:
- repr = "0" #XXX
+ repr = "0" # XXX Dont know what to do here at all?
else:
repr = str(value)
return repr
@@ -67,17 +69,10 @@
def __init__(self, translator):
self._translator = translator
self.obj2node = NormalizingDict()
- self.ptr2nodevalue = {}
self._pendingsetup = []
- self._pendingconstants = []
self._tmpcount = 1
- def addptrvalue(self, ptrvalue):
- value = ptrvalue._obj
- self.ptr2nodevalue[value] = self.create_constant_node(value, setup=True)
-
- def create_constant_node(self, value, setup=False):
- type_ = lltype.typeOf(value)
+ def create_constant_node(self, type_, value, setup=False):
node = None
if isinstance(type_, lltype.FuncType):
if value._callable and (not hasattr(value, "graph") or value.graph is None
@@ -94,21 +89,28 @@
elif isinstance(type_, lltype.Array):
node = ArrayNode(self, value)
- assert node is not None, "%s not supported" % lltype.typeOf(value)
+
+ elif isinstance(type_, lltype.OpaqueType):
+ node = OpaqueNode(self, value)
+
+ assert node is not None, "%s not supported %s" % (type_, lltype.typeOf(value))
if setup:
node.setup()
return node
-
+
def addpending(self, key, node):
+ # santity check we at least have a key of the right type
+ assert (isinstance(key, lltype.LowLevelType) or
+ isinstance(key, Constant) or
+ isinstance(lltype.typeOf(key), lltype.ContainerType))
+
assert key not in self.obj2node, (
"node with key %r already known!" %(key,))
+
+ log("added to pending nodes:", type(key), node)
self.obj2node[key] = node
- log("added to pending nodes:", node)
- if isinstance(node, (StructNode, ArrayNode)):
- self._pendingconstants.append(node)
- else:
- self._pendingsetup.append(node)
-
+ self._pendingsetup.append(node)
+
def prepare_repr_arg(self, const_or_var):
"""if const_or_var is not already in a dictionary self.obj2node,
the appropriate node gets constructed and gets added to
@@ -123,9 +125,9 @@
return
assert isinstance(ct, lltype.Ptr), "Preparation of non primitive and non pointer"
- value = const_or_var.value._obj
-
- self.addpending(const_or_var, self.create_constant_node(value))
+ value = const_or_var.value._obj
+
+ self.addpending(const_or_var, self.create_constant_node(ct.TO, value))
else:
log.prepare(const_or_var, type(const_or_var))
@@ -152,6 +154,9 @@
elif isinstance(type_, lltype.Array):
self.addpending(type_, ArrayTypeNode(self, type_))
+ elif isinstance(type_, lltype.OpaqueType):
+ self.addpending(type_, OpaqueTypeNode(self, type_))
+
else:
assert False, "need to prepare typerepr %s %s" % (type_, type(type_))
@@ -164,24 +169,35 @@
self.prepare_repr_arg_type(const_or_var.concretetype)
self.prepare_repr_arg(const_or_var)
+ def prepare_ptr(self, ptrvalue):
+ assert isinstance(lltype.typeOf(ptrvalue), lltype.Ptr)
+ value = ptrvalue._obj
+ type_ = lltype.typeOf(ptrvalue).TO
+ if value in self.obj2node or value is None:
+ return
+ self.addpending(value,
+ self.create_constant_node(type_, value))
+
def setup_all(self):
+ # Constants setup need to be done after the rest
+ pendingconstants = []
while self._pendingsetup:
- x = self._pendingsetup.pop()
- log.settingup(x)
- x.setup()
-
- while self._pendingconstants:
- x = self._pendingconstants.pop()
- log.settingup_constant(x)
- x.setup()
-
-
- def getobjects(self, subset_types=None):
- res = []
- for v in self.obj2node.values() + self.ptr2nodevalue.values():
- if subset_types is None or isinstance(v, subset_types):
- res.append(v)
- return res
+ node = self._pendingsetup.pop()
+ if isinstance(node, (StructNode, ArrayNode)):
+ pendingconstants.append(node)
+ continue
+ log.settingup(node)
+ node.setup()
+
+ self._pendingsetup = pendingconstants
+ while self._pendingsetup:
+ node = self._pendingsetup.pop()
+ assert isinstance(node, ConstantLLVMNode)
+ log.settingup_constant(node)
+ node.setup()
+
+ def getnodes(self):
+ return self.obj2node.values()
# __________________________________________________________
# Representing variables and constants in LLVM source code
@@ -222,26 +238,32 @@
def repr_arg_type_multi(self, args):
return [self.repr_arg_type(arg) for arg in args]
- def reprs_constant(self, value):
+ def repr_constant(self, value):
+ " returns node and repr as tuple "
type_ = lltype.typeOf(value)
if isinstance(type_, lltype.Primitive):
repr = primitive_to_str(type_, value)
- return "%s %s" % (self.repr_arg_type(type_), repr)
+ return None, "%s %s" % (self.repr_arg_type(type_), repr)
elif isinstance(type_, lltype.Ptr):
- node = self.ptr2nodevalue[value._obj]
+ toptr = self.repr_arg_type(type_)
+
+ # special case, null pointer
+ if value._obj is None:
+ return None, "%s null" % (toptr,)
+
+ node = self.obj2node[value._obj]
ref = node.ref
fromptr = node.castfrom()
- toptr = self.repr_arg_type(type_)
if fromptr:
refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref)
ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr)
- return "%s %s" % (toptr, ref)
+ return node, "%s %s" % (toptr, ref)
elif isinstance(type_, lltype.Array) or isinstance(type_, lltype.Struct):
- node = self.create_constant_node(value, setup=True)
- return node.constantvalue()
+ node = self.create_constant_node(type_, value, setup=True)
+ return node, node.constantvalue()
assert False, "%s not supported" % (type(value))
Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py Fri Jul 15 17:01:09 2005
@@ -4,7 +4,7 @@
from pypy.rpython import lltype
from pypy.translator.backendoptimization import remove_same_as
from pypy.translator.unsimplify import remove_double_links
-from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2.node import LLVMNode, ConstantLLVMNode
from pypy.translator.llvm2.atomic import is_atomic
from pypy.translator.llvm2.log import log
from pypy.rpython.extfunctable import table as extfunctable
@@ -17,7 +17,9 @@
self.db = db
assert isinstance(type_, lltype.FuncType)
self.type_ = type_
- self.ref = 'ft.%s.%s' % (type_, nextnum())
+ # XXX Make simplier for now, it is far too hard to read otherwise
+ #self.ref = 'ft.%s.%s' % (type_, nextnum())
+ self.ref = '%%ft.%s' % (nextnum(),)
def __str__(self):
return "<FuncTypeNode %r>" % self.ref
@@ -29,11 +31,9 @@
def writedatatypedecl(self, codewriter):
returntype = self.db.repr_arg_type(self.type_.RESULT)
inputargtypes = self.db.repr_arg_type_multi(self.type_._trueargs())
- decl = "%s type %s (%s)*" % (self.ref, returntype,
- ", ".join(inputargtypes))
codewriter.funcdef(self.ref, returntype, inputargtypes)
-class FuncNode(LLVMNode):
+class FuncNode(ConstantLLVMNode):
_issetup = False
def __init__(self, db, value):
Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Jul 15 17:01:09 2005
@@ -49,18 +49,18 @@
nl = codewriter.newline
nl(); comment("Type Declarations"); nl()
- for typ_decl in self.db.getobjects():
+ for typ_decl in self.db.getnodes():
typ_decl.writedatatypedecl(codewriter)
nl(); comment("Global Data") ; nl()
- for typ_decl in self.db.getobjects():
+ for typ_decl in self.db.getnodes():
typ_decl.writeglobalconstants(codewriter)
nl(); comment("Function Prototypes") ; nl()
if self.embedexterns:
for extdecl in extdeclarations.split('\n'):
codewriter.append(extdecl)
- for typ_decl in self.db.getobjects():
+ for typ_decl in self.db.getnodes():
typ_decl.writedecl(codewriter)
#import pdb ; pdb.set_trace()
@@ -73,7 +73,7 @@
for extfunc in gc_funcs.split('\n'):
codewriter.append(extfunc)
- for typ_decl in self.db.getobjects():
+ for typ_decl in self.db.getnodes():
typ_decl.writeimpl(codewriter)
depdone = {}
Modified: pypy/dist/pypy/translator/llvm2/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/node.py (original)
+++ pypy/dist/pypy/translator/llvm2/node.py Fri Jul 15 17:01:09 2005
@@ -47,3 +47,8 @@
# __________________ after "implementation" ____________________
def writeimpl(self, codewriter):
""" write function implementations. """
+
+class ConstantLLVMNode(LLVMNode):
+
+ def castfrom(self):
+ return None
Added: pypy/dist/pypy/translator/llvm2/opaquenode.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm2/opaquenode.py Fri Jul 15 17:01:09 2005
@@ -0,0 +1,27 @@
+from pypy.translator.llvm2.node import LLVMNode, ConstantLLVMNode
+from pypy.rpython import lltype
+
+class OpaqueTypeNode(LLVMNode):
+
+ def __init__(self, db, opaquetype):
+ assert isinstance(opaquetype, lltype.OpaqueType)
+ self.db = db
+ self.opaquetype = opaquetype
+ self.ref = "%%opaque.%s" % (opaquetype.tag)
+
+ def __str__(self):
+ return "<OpaqueNode %r>" %(self.ref,)
+
+ # ______________________________________________________________________
+ # main entry points from genllvm
+
+ def writedatatypedecl(self, codewriter):
+ # XXX Dummy - not sure what what we want
+ codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *'])
+
+
+class OpaqueNode(ConstantLLVMNode):
+ def __init__(self, db, value):
+ self.db = db
+ self.value = value
+ self.ref = "null"
Modified: pypy/dist/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/structnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/structnode.py Fri Jul 15 17:01:09 2005
@@ -1,6 +1,6 @@
import py
from pypy.translator.llvm2.log import log
-from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2.node import LLVMNode, ConstantLLVMNode
from pypy.translator.llvm2 import varsize
from pypy.rpython import lltype
@@ -77,7 +77,7 @@
self.ref, self.constructor_decl, arraytype,
indices_to_array)
-class StructNode(LLVMNode):
+class StructNode(ConstantLLVMNode):
""" A struct constant. Can simply contain
a primitive,
a struct,
@@ -90,7 +90,7 @@
self.value = value
self.structtype = self.value._TYPE
self.ref = "%%stinstance.%s" % (nextnum(),)
-
+
def __str__(self):
return "<StructNode %r>" % (self.ref,)
@@ -98,27 +98,27 @@
return [(name, self.structtype._flds[name])
for name in self.structtype._names_without_voids()]
+ def _getvalues(self):
+ values = []
+ for name, T in self._gettypes():
+ value = getattr(self.value, name)
+ values.append(self.db.repr_constant(value)[1])
+ return values
+
def setup(self):
for name, T in self._gettypes():
assert T is not lltype.Void
if isinstance(T, lltype.Ptr):
- self.db.addptrvalue(getattr(self.value, name))
+ self.db.prepare_ptr(getattr(self.value, name))
self._issetup = True
- def castfrom(self):
- return None
-
- def get_typestr(self):
+ def get_typerepr(self):
return self.db.repr_arg_type(self.structtype)
def constantvalue(self):
""" Returns the constant representation for this node. """
- values = []
- for name, T in self._gettypes():
- value = getattr(self.value, name)
- values.append(self.db.reprs_constant(value))
-
- return "%s {%s}" % (self.get_typestr(), ", ".join(values))
+ values = self._getvalues()
+ return "%s {%s}" % (self.get_typerepr(), ", ".join(values))
# ______________________________________________________________________
# main entry points from genllvm
@@ -141,31 +141,44 @@
def __str__(self):
return "<StructVarsizeNode %r>" % (self.ref,)
+ def _getvalues(self):
+ values = []
+ for name, T in self._gettypes()[:-1]:
+ value = getattr(self.value, name)
+ values.append(self.db.repr_constant(value)[1])
+ values.append(self._get_lastnoderepr())
+ return values
+
+ def _get_lastnode(self):
+ if not hasattr(self, "lastnode"):
+ lastname, LASTT = self._gettypes()[-1]
+ assert isinstance(LASTT, lltype.Array) or (
+ isinstance(LASTT, lltype.Struct) and LASTT._arrayfld)
+ value = getattr(self.value, lastname)
+ self.lastnode, self.lastnode_repr = self.db.repr_constant(value)
+ return self.lastnode
+
+ def _get_lastnoderepr(self):
+ self._get_lastnode()
+ return self.lastnode_repr
+
def setup(self):
# set castref (note we must ensure that types are "setup" before we can
# get typeval)
typeval = self.db.repr_arg_type(lltype.typeOf(self.value))
- self.castref = "cast (%s* %s to %s*)" % (self.get_typestr(),
+ self.castref = "cast (%s* %s to %s*)" % (self.get_typerepr(),
self.ref,
typeval)
super(StructVarsizeNode, self).setup()
+
+ def get_typerepr(self):
+ # last type is a special case and need to be worked out recursively
+ types = self._gettypes()[:-1]
+ types_repr = [self.db.repr_arg_type(T) for name, T in types]
+ types_repr.append(self._get_lastnode().get_typerepr())
- def get_typestr(self):
- lastname, LASTT = self._gettypes()[-1]
- assert isinstance(LASTT, lltype.Array) or (
- isinstance(LASTT, lltype.Struct) and LASTT._arrayfld)
-
- #XXX very messy
- node = self.db.create_constant_node(getattr(self.value, lastname), True)
- lasttype = node.get_typestr()
-
- types = []
- for name, T in self._gettypes()[:-1]:
- types.append(self.db.repr_arg_type(T))
- types.append(lasttype)
-
- return "{%s}" % ", ".join(types)
+ return "{%s}" % ", ".join(types_repr)
def castfrom(self):
- return "%s*" % self.get_typestr()
+ return "%s*" % self.get_typerepr()
Modified: pypy/dist/pypy/translator/llvm2/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/test_lltype.py (original)
+++ pypy/dist/pypy/translator/llvm2/test/test_lltype.py Fri Jul 15 17:01:09 2005
@@ -178,3 +178,13 @@
fn = compile_function(array_constant, [], embedexterns=False)
assert fn() == 42
+def test_struct_opaque():
+ PRTTI = lltype.Ptr(lltype.RuntimeTypeInfo)
+ S = lltype.GcStruct('s', ('a', lltype.Signed), ('r', PRTTI))
+ s = lltype.malloc(S)
+ s.a = 42
+ def array_constant():
+ return s.a
+ fn = compile_function(array_constant, [], embedexterns=False)
+ assert fn() == 42
+
More information about the Pypy-commit
mailing list