[pypy-svn] r49424 - pypy/dist/pypy/translator/llvm
rxe at codespeak.net
rxe at codespeak.net
Wed Dec 5 23:10:17 CET 2007
Author: rxe
Date: Wed Dec 5 23:10:16 2007
New Revision: 49424
Modified:
pypy/dist/pypy/translator/llvm/arraynode.py
pypy/dist/pypy/translator/llvm/codewriter.py
pypy/dist/pypy/translator/llvm/database.py
pypy/dist/pypy/translator/llvm/externs2ll.py
pypy/dist/pypy/translator/llvm/genllvm.py
pypy/dist/pypy/translator/llvm/modwrapper.py
pypy/dist/pypy/translator/llvm/node.py
pypy/dist/pypy/translator/llvm/opaquenode.py
pypy/dist/pypy/translator/llvm/opwriter.py
pypy/dist/pypy/translator/llvm/structnode.py
pypy/dist/pypy/translator/llvm/typedefnode.py
Log:
rewrite of pbc code. it is quite simple now.
the old code was written before knowledge of parentlink() and
was somehow stitched up to work for the last 2.5 years - but i had no idea how it worked and i wrote
it. so just threw it all away... :-)
the emitted code is now one getelementptr instead of a nested list of them that could extend across about 100 lines
so
store %structtype_object_vtable*
getelementptr(%structtype_pypy.translator.goal.richards.TaskState_vtable*
getelementptr(%structtype_pypy.translator.goal.richards.Task_vtable*
getelementptr(%structtype_pypy.translator.goal.richards.IdleTask_vtable*
@s_inst_pypy.translator.goal.richards.IdleTask_vtable, i32 0, i32 0),
i32 0, i32 0), i32 0, i32 0), %structtype_object_vtable** %tmp_17
now looks like
store %structtype_object_vtable* getelementptr(%structtype_IdleTaskRec_vtable* @s_inst_IdleTaskRec_vtable, i32 0, i32 0, i32 0), %structtype_object_
vtable** %tmp_99
also some random simplications.
Modified: pypy/dist/pypy/translator/llvm/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/arraynode.py (original)
+++ pypy/dist/pypy/translator/llvm/arraynode.py Wed Dec 5 23:10:16 2007
@@ -15,12 +15,6 @@
def constantvalue(self):
return '%s c"%s\\00"' % (self.get_typerepr(), self.value)
-
- def get_childref(self, index):
- return "getelementptr(%s* %s, i32 0, i32 %s)" % (
- self.get_typerepr(),
- self.name,
- index)
def writeglobalconstants(self, codewriter):
codewriter.globalinstance(self.ref, self.constantvalue())
@@ -69,33 +63,6 @@
typeval = self.db.repr_type(self.arraytype)
return "{ %s, [%s x %s] }" % (self.db.get_machine_word(),
arraylen, typeval)
-
- def get_ref(self):
- typeval = self.db.repr_type(lltype.typeOf(self.value))
- p, c = lltype.parentlink(self.value)
- if p is None:
- ref = self.name
- else:
- ref = self.db.get_childref(p, c)
-
- ref = "bitcast(%s* %s to %s*)" % (self.get_typerepr(),
- ref,
- typeval)
- return ref
-
- def get_pbcref(self, toptr):
- p, c = lltype.parentlink(self.value)
- assert p is None, "child PBC arrays are NOT needed by rtyper"
-
- fromptr = "%s*" % self.get_typerepr()
- ref = "bitcast(%s %s to %s)" % (fromptr, self.name, toptr)
- return ref
-
- def get_childref(self, index):
- return "getelementptr(%s* %s, i32 0, i32 1, i32 %s)" % (
- self.get_typerepr(),
- self.name,
- index)
def constantvalue(self):
physicallen, arrayrepr = self.get_arrayvalue()
@@ -108,20 +75,13 @@
typeval,
arrayrepr)
- s = "%s {%s}" % (self.get_typerepr(), value)
- return s
+ return "%s {%s}" % (self.get_typerepr(), value)
class ArrayNoLengthNode(ArrayNode):
def get_typerepr(self):
arraylen = self.get_arrayvalue()[0]
typeval = self.db.repr_type(self.arraytype)
return "[%s x %s]" % (arraylen, typeval)
-
- def get_childref(self, index):
- return "getelementptr(%s* %s, i32 0, i32 %s)" %(
- self.get_typerepr(),
- self.name,
- index)
def constantvalue(self):
physicallen, arrayrepr = self.get_arrayvalue()
@@ -164,6 +124,9 @@
name = '' #str(value).split()[1]
self.make_name(name)
+ def get_typerepr(self):
+ return '[%s x i8]' % self.get_length()
+
def constantvalue(self):
return "{ %s } {%s %s}" % (self.db.get_machine_word(),
self.db.get_machine_word(),
Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py (original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py Wed Dec 5 23:10:16 2007
@@ -172,6 +172,7 @@
self._indent("free %s %s" % (vartype, varref))
def debug_print(self, s):
+ XXX # fixme
var = self.db.repr_tmpvar()
node = self.db.create_debug_string(s)
self.call(var, "i32", "@write",
Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py (original)
+++ pypy/dist/pypy/translator/llvm/database.py Wed Dec 5 23:10:16 2007
@@ -1,4 +1,3 @@
-
import sys
from pypy.translator.llvm.log import log
@@ -22,6 +21,17 @@
log = log.database
+def var_size_type(T):
+ " returns None if T not varsize "
+ if not T._is_varsize():
+ return None
+ elif isinstance(T, lltype.Array):
+ return T.OF
+ elif isinstance(T, lltype.Struct):
+ return T._arrayfld
+ else:
+ assert False, "unknown type"
+
class Database(object):
def __init__(self, genllvm, translator):
self.genllvm = genllvm
@@ -43,6 +53,7 @@
#_______debuggging______________________________________
def dump_pbcs(self):
+ XXX#FIXME
r = ""
for k, v in self.obj2node.iteritems():
@@ -58,13 +69,10 @@
p, _ = lltype.parentlink(k)
ref = v.get_ref()
type_ = self.repr_type(lltype.Ptr(lltype.typeOf(k)))
- pbc_ref = v.get_pbcref(type_)
-
r += "\ndump_pbcs %s (%s)\n" \
"parent %s\n" \
"type %s\n" \
- "getref -> %s \n" \
- "pbcref -> %s \n" % (v, k, p, type_, ref, pbc_ref)
+ "getref -> %s \n" % (v, k, p, type_, ref)
return r
#_______setting up and preparation______________________________
@@ -113,7 +121,7 @@
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
@@ -242,6 +250,87 @@
# __________________________________________________________
# Representing variables and constants in LLVM source code
+ def to_getelementptr(self, value):
+ # so we build the thing up instead
+ p = value
+ children = []
+ while True:
+ p, c = lltype.parentlink(p)
+ if p is None:
+ break
+ children.append((p, c))
+
+ children.reverse()
+
+ TYPE = lltype.typeOf(children[0][0])
+ parentnode = self.obj2node[children[0][0]]
+
+ indices = [("i32", 0)]
+
+ for _, ii in children:
+ name = None
+
+ # this is because FixedSizeArray can sometimes be accessed like an
+ # Array and then sometimes a Struct
+ if isinstance(ii, str):
+ name = ii
+ assert name in list(TYPE._names)
+ fieldnames = TYPE._names_without_voids()
+ indexref = fieldnames.index(name)
+ else:
+ indexref = ii
+
+ if isinstance(TYPE, lltype.FixedSizeArray):
+ indices.append(("i32", indexref))
+ TYPE = TYPE.OF
+
+ elif isinstance(TYPE, lltype.Array):
+ if not TYPE._hints.get("nolength", False):
+ indices.append(("i32", 1))
+ indices.append(("i32", indexref))
+ TYPE = TYPE.OF
+
+ elif isinstance(TYPE, lltype.Struct):
+ assert name is not None
+ TYPE = getattr(TYPE, name)
+ indices.append(("i32", indexref))
+
+ else:
+ raise Exception("unsupported type: %s" % TYPE)
+
+ indices_str = ', '.join ([('%s %s' % (x,y)) for x, y in indices])
+ ref = "getelementptr(%s* %s, %s)" % (
+ parentnode.get_typerepr(),
+ parentnode.ref,
+ indices_str)
+
+ return ref
+
+ def get_ref(self, value):
+ node = self.obj2node[value]
+ T = lltype.typeOf(value)
+ p, c = lltype.parentlink(value)
+ if p is None:
+ ref = node.ref
+ VT = var_size_type(T)
+ if VT and VT is not lltype.Void:
+ ref = "bitcast(%s* %s to %s*)" % (node.get_typerepr(),
+ ref,
+ self.repr_type(T))
+ else:
+ ref = self.to_getelementptr(value)
+
+ if isinstance(node, FixedSizeArrayNode):
+ assert isinstance(value, lltype._subarray)
+
+ # XXX UGLY (but needs fixing outside of genllvm)
+ # ptr -> array of len 1 (for now, since operations expect this)
+ ref = "bitcast(%s* %s to %s*)" % (self.repr_type(T.OF),
+ ref,
+ self.repr_type(T))
+
+ return ref
+
def repr_arg(self, arg):
if isinstance(arg, Constant):
if isinstance(arg.concretetype, lltype.Primitive):
@@ -251,8 +340,7 @@
if not arg.value:
return 'null'
else:
- node = self.obj2node[arg.value._obj]
- return node.get_ref()
+ return self.get_ref(arg.value._obj)
else:
assert isinstance(arg, Variable)
return "%" + str(arg)
@@ -298,7 +386,7 @@
return None, "%s null" % toptr
node = self.obj2node[value]
- ref = node.get_pbcref(toptr)
+ ref = self.get_ref(value)
return node, "%s %s" % (toptr, ref)
elif isinstance(type_, (lltype.Array, lltype.Struct)):
@@ -331,10 +419,6 @@
return True
return False
- def get_childref(self, parent, child):
- node = self.obj2node[parent]
- return node.get_childref(child)
-
def create_debug_string(self, s):
r = DebugStrNode(s)
self.debugstringnodes.append(r)
Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py (original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py Wed Dec 5 23:10:16 2007
@@ -65,7 +65,7 @@
ccode = []
if standalone:
- ccode.append('#define __ENTRY_POINT__ %s' % entrynode.get_ref()[1:])
+ ccode.append('#define __ENTRY_POINT__ %s' % entrynode.ref[1:])
ccode.append('#define ENTRY_POINT_DEFINED 1')
sio = StringIO()
Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Dec 5 23:10:16 2007
@@ -154,9 +154,9 @@
return codewriter
def setup_externs(self, c_db, db):
- # XXX
+ # XXX this should be done via augmenting entrypoint
exctransformer = c_db.exctransformer
- for obj in [exctransformer._rpyexc_occured_ptr.value,
+ for obj in [exctransformer.rpyexc_occured_ptr.value,
exctransformer.rpyexc_fetch_type_ptr.value,
exctransformer.rpyexc_clear_ptr.value]:
db.prepare_constant(lltype.typeOf(obj), obj)
Modified: pypy/dist/pypy/translator/llvm/modwrapper.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/modwrapper.py (original)
+++ pypy/dist/pypy/translator/llvm/modwrapper.py Wed Dec 5 23:10:16 2007
@@ -14,9 +14,9 @@
_c = ctypes.CDLL(join(dirname(realpath(__file__)), "%s"))
-rpyexc_occured = _c.pypy__rpyexc_occured
+rpyexc_occured = _c.pypy_rpyexc_occured
rpyexc_occured.argtypes = []
-rpyexc_occured.restype = ctypes.c_int
+rpyexc_occured.restype = ctypes.c_byte
rpyexc_fetch_type = _c.pypy_rpyexc_fetch_type
rpyexc_fetch_type.argtypes = []
Modified: pypy/dist/pypy/translator/llvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/node.py (original)
+++ pypy/dist/pypy/translator/llvm/node.py Wed Dec 5 23:10:16 2007
@@ -8,12 +8,13 @@
nodename_count = {}
def mangle(self, name):
if name not in self.nodename_count:
- result = name
self.nodename_count[name] = 1
- return result
+ return name
else:
result = '%s_%d' % (name, self.nodename_count[name])
self.nodename_count[name] += 1
+ # this ensures (a) doesn exist yet, and (b) adds it to the
+ # dictionary just to prevent some function called xxx_42() and clashing
return self.mangle(result)
def make_name(self, name=''):
@@ -44,14 +45,6 @@
class FuncNode(Node):
- # XXX proof that the whole llvm is hanging on a bunch of loose stitches
- def get_ref(self):
- return self.ref
-
- # XXX proof that the whole llvm is hanging on a bunch of loose stitches
- def get_pbcref(self, _):
- return self.ref
-
def writedecl(self, codewriter):
" write function forward declarations "
pass
@@ -63,18 +56,6 @@
class ConstantNode(Node):
__slots__ = "".split()
- def get_ref(self):
- # XXX tmp
- return self.ref
-
- def get_childref(self, index):
- """ Returns a reference as used for operations in blocks for internals of a pbc. """
- raise AttributeError("Must be implemented in subclass")
-
- def get_pbcref(self, toptr):
- """ Returns a reference as a pointer used per pbc. """
- return self.ref
-
# ______________________________________________________________________
# entry points from genllvm
Modified: pypy/dist/pypy/translator/llvm/opaquenode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opaquenode.py (original)
+++ pypy/dist/pypy/translator/llvm/opaquenode.py Wed Dec 5 23:10:16 2007
@@ -15,7 +15,6 @@
def __init__(self, db, value):
self.db = db
self.value = value
- self._get_ref_cache = None
name = str(value).split()[1]
self.make_name(name)
@@ -23,18 +22,6 @@
# ______________________________________________________________________
# main entry points from genllvm
- def get_ref(self):
- """ Returns a reference as used for operations in blocks. """
- if self._get_ref_cache:
- return self._get_ref_cache
- p, c = lltype.parentlink(self.value)
- if p is None:
- ref = self.name
- else:
- ref = self.db.get_childref(p, c)
- self._get_ref_cache = ref
- return ref
-
def writeglobalconstants(self, codewriter):
pass
Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py (original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py Wed Dec 5 23:10:16 2007
@@ -26,18 +26,6 @@
self.rettype = "%s (%s)*" % (self.rettype,
", ".join(self.argtypes[1:]))
-class OpReprInvoke(OpReprCall):
- __slots__ = "db op retref rettype argrefs argtypes functionref".split()
- def __init__(self, op, db):
- super(OpReprInvoke, self).__init__(op, db)
-
- if op.opname in ('direct_call', 'indirect_call'):
- self.functionref = self.argrefs[0]
- self.argrefs = self.argrefs[1:]
- self.argtypes = self.argtypes[1:]
- else:
- self.functionref = '%pypyop_' + op.opname
-
class OpWriter(object):
shift_operations = {
@@ -123,7 +111,6 @@
return indices
def write_operation(self, op):
-
if self.db.genllvm.config.translation.llvm.debug:
self.codewriter.comment(str(op))
#self.codewriter.debug_print(str(op) + "\n")
Modified: pypy/dist/pypy/translator/llvm/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/structnode.py (original)
+++ pypy/dist/pypy/translator/llvm/structnode.py Wed Dec 5 23:10:16 2007
@@ -12,12 +12,7 @@
return index
class StructNode(ConstantNode):
- """ A struct constant. Can simply contain
- a primitive,
- a struct,
- pointer to struct/array
- """
- __slots__ = "db value structtype _get_ref_cache _get_types".split()
+ __slots__ = "db value structtype _get_types".split()
prefix = '@s_inst_'
@@ -25,8 +20,8 @@
self.db = db
self.value = value
self.structtype = self.value._TYPE
- name = str(value).split()[1]
- self._get_ref_cache = None
+ parts = str(value).split()[1]
+ name = parts.split('.')[-1]
self._get_types = self._compute_types()
self.make_name(name)
@@ -53,38 +48,6 @@
def get_typerepr(self):
return self.db.repr_type(self.structtype)
-
- def get_childref(self, index):
- pos = 0
- found = False
- for name in self.structtype._names_without_voids():
- if name == index:
- found = True
- break
- pos += 1
-
- return "getelementptr(%s* %s, i32 0, i32 %s)" %(
- self.get_typerepr(),
- self.get_ref(),
- pos)
-
- def get_ref(self):
- """ Returns a reference as used for operations in blocks. """
- # XXX cache here is **dangerous** considering it can return different values :-(
- # XXX should write a test to prove this
- #if self._get_ref_cache:
- # return self._get_ref_cache
- p, c = lltype.parentlink(self.value)
- if p is None:
- ref = self.name
- else:
- ref = self.db.get_childref(p, c)
- #XXXself._get_ref_cache = ref
- return ref
-
- def get_pbcref(self, toptr):
- """ Returns a reference as used per pbc. """
- return self.get_ref()
def constantvalue(self):
""" Returns the constant representation for this node. """
@@ -95,7 +58,7 @@
else:
all_values = ", ".join(values)
return "%s { %s }" % (self.get_typerepr(), all_values)
-
+
class FixedSizeArrayNode(StructNode):
prefix = '@fa_inst_'
@@ -110,40 +73,8 @@
all_values = ",\n ".join(values)
return "%s [\n %s\n ]\n" % (self.get_typerepr(), all_values)
- def get_ref(self):
- p, c = lltype.parentlink(self.value)
- if p is None:
- ref = self.name
- else:
- ref = self.db.get_childref(p, c)
- if isinstance(self.value, lltype._subarray):
- # ptr -> array of len 1
- ref = "bitcast(%s* %s to %s*)" % (self.db.repr_type(self.arraytype),
- ref,
- self.db.repr_type(lltype.typeOf(self.value)))
- return ref
-
- def get_childref(self, index):
- if isinstance(index, str):
- pos = 0
- found = False
- for name in self.structtype._names_without_voids():
- if name == index:
- found = True
- break
- pos += 1
- else:
- pos = index
-
- return "getelementptr(%s* %s, i32 0, i32 %s)" % (
- self.get_typerepr(),
- self.get_ref(),
- pos)
-
def setup(self):
if isinstance(self.value, lltype._subarray):
- # XXX what is this?
- # self.value._parentstructure()
p, c = lltype.parentlink(self.value)
if p is not None:
self.db.prepare_constant(lltype.typeOf(p), p)
@@ -151,17 +82,6 @@
super(FixedSizeArrayNode, self).setup()
class StructVarsizeNode(StructNode):
- """ A varsize struct constant. Can simply contain
- a primitive,
- a struct,
- pointer to struct/array
-
- and the last element *must* be
- an array
- OR
- a series of embedded structs, which has as its last element an array.
- """
-
prefix = '@sv_inst_'
def _getvalues(self):
@@ -199,39 +119,3 @@
result = "{%s}" % ", ".join(types_repr)
self._get_typerepr_cache = result
return result
-
- def get_childref(self, index):
- pos = 0
- found = False
- for name in self.structtype._names_without_voids():
- if name == index:
- found = True
- break
- pos += 1
- assert found
-
- ref = "getelementptr(%s* %s, i32 0, i32 %s)" %(
- self.get_typerepr(),
- super(StructVarsizeNode, self).get_ref(),
- pos)
-
- return ref
-
- def get_ref(self):
- ref = super(StructVarsizeNode, self).get_ref()
- typeval = self.db.repr_type(lltype.typeOf(self.value))
- ref = "bitcast(%s* %s to %s*)" % (self.get_typerepr(),
- ref,
- typeval)
- return ref
-
- def get_pbcref(self, toptr):
- """ Returns a reference as used per pbc. """
- ref = self.name
- p, c = lltype.parentlink(self.value)
- assert p is None, "child varsize struct are NOT needed by rtyper"
- fromptr = "%s*" % self.get_typerepr()
- refptr = "getelementptr(%s %s, i32 0)" % (fromptr, ref)
- ref = "bitcast(%s %s to %s)" % (fromptr, refptr, toptr)
- return ref
-
Modified: pypy/dist/pypy/translator/llvm/typedefnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/typedefnode.py (original)
+++ pypy/dist/pypy/translator/llvm/typedefnode.py Wed Dec 5 23:10:16 2007
@@ -64,7 +64,9 @@
assert isinstance(STRUCT, lltype.Struct)
self.db = db
self.STRUCT = STRUCT
- self.make_name(self.STRUCT._name)
+ parts = self.STRUCT._name.split('.')
+ name = parts[-1]
+ self.make_name(name)
def _fields(self):
return [getattr(self.STRUCT, name)
More information about the Pypy-commit
mailing list