[pypy-svn] r15993 - pypy/dist/pypy/translator/llvm2
rxe at codespeak.net
rxe at codespeak.net
Fri Aug 12 01:31:57 CEST 2005
Author: rxe
Date: Fri Aug 12 01:31:53 2005
New Revision: 15993
Modified:
pypy/dist/pypy/translator/llvm2/arraynode.py
pypy/dist/pypy/translator/llvm2/codewriter.py
pypy/dist/pypy/translator/llvm2/database.py
pypy/dist/pypy/translator/llvm2/node.py
pypy/dist/pypy/translator/llvm2/opwriter.py
pypy/dist/pypy/translator/llvm2/pyxwrapper.py
pypy/dist/pypy/translator/llvm2/structnode.py
pypy/dist/pypy/translator/llvm2/varsize.py
Log:
A first attempt at getting genllvm2 to work on 64 bit machines.
Not everything is working... yet. Mostly externals and some exceptions (ones
that involve external code); this is another reason why we should at least aim
to generate the code instead of hand-coding it - I guess. But we know that!
Also in this checkin:
* Annotated some commented out code with XXX and reasons
* Got rid of some horrendously long and unreabable names of generated ArrayTypeNodes
Modified: pypy/dist/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/arraynode.py (original)
+++ pypy/dist/pypy/translator/llvm2/arraynode.py Fri Aug 12 01:31:53 2005
@@ -14,17 +14,28 @@
self.db = db
self.array = array
- self.arraytype = array.OF
+ arraytype = self.arraytype = array.OF
# ref is used to reference the arraytype in llvm source
# constructor_ref is used to reference the constructor
# for the array type in llvm source code
# constructor_decl is used to declare the constructor
# for the array type (see writeimpl)
c = nextnum()
- self.ref = "%%arraytype.%s.%s" % (c, self.arraytype)
- self.constructor_ref = "%%new.array.%s" % c
- self.constructor_decl = "%s * %s(int %%len)" % \
- (self.ref, self.constructor_ref)
+ name = ""
+ if isinstance(arraytype, lltype.Ptr):
+ name += "ptr_"
+ arraytype = arraytype.TO
+ if hasattr(arraytype, "_name"):
+ name += arraytype._name
+ else:
+ name += str(arraytype)
+
+ self.ref = self.make_ref('%arraytype.', name)
+ self.constructor_ref = self.make_ref('%new.array.', name)
+ self.constructor_decl = "%s * %s(%s %%len)" % \
+ (self.ref,
+ self.constructor_ref,
+ self.db.get_machine_word())
def __str__(self):
return "<ArrayTypeNode %r>" % self.ref
@@ -45,7 +56,9 @@
# entry points from genllvm
#
def writedatatypedecl(self, codewriter):
- codewriter.arraydef(self.ref, self.db.repr_arg_type(self.arraytype))
+ codewriter.arraydef(self.ref,
+ self.db.get_machine_word(),
+ self.db.repr_arg_type(self.arraytype))
def writedecl(self, codewriter):
# declaration for constructor
@@ -54,7 +67,7 @@
def writeimpl(self, codewriter):
log.writeimpl(self.ref)
fromtype = self.db.repr_arg_type(self.arraytype)
- varsize.write_constructor(codewriter, self.ref,
+ varsize.write_constructor(self.db, codewriter, self.ref,
self.constructor_decl,
fromtype,
atomicmalloc=self.is_atomic())
@@ -63,10 +76,11 @@
def __init__(self, db, array):
assert isinstance(array, lltype.Array)
+ self.db = db
self.ref = "%arraytype.Void"
def writedatatypedecl(self, codewriter):
- td = "%s = type { int }" % self.ref
+ td = "%s = type { %s }" % (self.ref, self.db.get_machine_word())
codewriter.append(td)
class ArrayNode(ConstantLLVMNode):
@@ -108,7 +122,8 @@
def get_typerepr(self):
arraylen = self.get_arrayvalue()[0]
typeval = self.db.repr_arg_type(self.arraytype)
- return "{ int, [%s x %s] }" % (arraylen, typeval)
+ return "{ %s, [%s x %s] }" % (self.db.get_machine_word(),
+ arraylen, typeval)
def get_ref(self):
typeval = self.db.repr_arg_type(lltype.typeOf(self.value))
@@ -145,10 +160,11 @@
typeval = self.db.repr_arg_type(self.arraytype)
# first length is logical, second is physical
- value = "int %s, [%s x %s] %s" % (self.get_length(),
- physicallen,
- typeval,
- arrayrepr)
+ value = "%s %s, [%s x %s] %s" % (self.db.get_machine_word(),
+ self.get_length(),
+ physicallen,
+ typeval,
+ arrayrepr)
s = "%s {%s}" % (self.get_typerepr(), value)
return s
@@ -164,15 +180,6 @@
item_length = len(items)
if item_length == 0 or items[-1] != chr(0):
items = items + [chr(0)]
- l = item_length + 1
- r = "".join([self.db.repr_constant(v)[1] for v in items])
- return l, r
-
- def get_arrayvalue(self):
- items = self.value.items
- item_length = len(items)
- if item_length == 0 or items[-1] != chr(0):
- items = items + [chr(0)]
item_length += 1
s = []
for c in items:
@@ -188,9 +195,12 @@
def __init__(self, db, value):
assert isinstance(lltype.typeOf(value), lltype.Array)
+ self.db = db
self.ref = self.make_ref('%arrayinstance', '')
self.value = value
def constantvalue(self):
- return "{ int } {int %s}" % len(self.value.items)
+ return "{ %s } {%s %s}" % (self.db.get_machine_word(),
+ self.db.get_machine_word(),
+ len(self.value.items))
Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py (original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py Fri Aug 12 01:31:53 2005
@@ -41,8 +41,8 @@
def structdef(self, name, typereprs):
self.append("%s = type { %s }" %(name, ", ".join(typereprs)))
- def arraydef(self, name, typerepr):
- self.append("%s = type { int, [0 x %s] }" % (name, typerepr))
+ def arraydef(self, name, lentype, typerepr):
+ self.append("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr))
def funcdef(self, name, rettyperepr, argtypereprs):
self.append("%s = type %s (%s)" % (name, rettyperepr,
Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py (original)
+++ pypy/dist/pypy/translator/llvm2/database.py Fri Aug 12 01:31:53 2005
@@ -1,3 +1,4 @@
+import sys
from pypy.translator.llvm2.log import log
from pypy.translator.llvm2.funcnode import FuncNode, FuncTypeNode
from pypy.translator.llvm2.extfuncnode import ExternalFuncNode
@@ -13,14 +14,6 @@
log = log.database
-PRIMITIVES_TO_LLVM = {lltype.Signed: "int",
- lltype.Char: "sbyte",
- lltype.Unsigned: "uint",
- lltype.Bool: "bool",
- lltype.Float: "double",
- lltype.UniChar: "uint",
- lltype.Void: "void"}
-
class NormalizingDict(object):
""" this is a helper dict for obj2node in order
to allow saner key-unification for Ptrs to functions
@@ -60,17 +53,6 @@
def items(self):
return self._dict.items()
-def primitive_to_str(type_, value):
- if type_ is lltype.Bool:
- repr = str(value).lower() #False --> false
- elif type_ is lltype.Char:
- repr = str(ord(value))
- elif type_ is lltype.UniChar:
- repr = str(ord(value))
- else:
- repr = str(value)
- return repr
-
class Database(object):
def __init__(self, translator):
self._translator = translator
@@ -81,6 +63,33 @@
# debug operation comments
self._opcomments = {}
+ self.primitives_init()
+
+ def primitives_init(self):
+ primitives = {
+ lltype.Char: "sbyte",
+ lltype.Bool: "bool",
+ lltype.Float: "double",
+ lltype.UniChar: "uint",
+ lltype.Void: "void"}
+
+ # 32 bit platform
+ if sys.maxint == 2**31-1:
+ primitives.update({
+ lltype.Signed: "int",
+ lltype.Unsigned: "uint" })
+
+ # 64 bit platform
+ elif sys.maxint == 2**63-1:
+ primitives.update({
+ lltype.Signed: "long",
+ lltype.Unsigned: "ulong" })
+
+ else:
+ assert False, "Unsupported platform"
+
+ self.primitives = primitives
+
#_______for debugging llvm code_________________________
def add_op2comment(self, lenofopstr, op):
@@ -270,11 +279,11 @@
# __________________________________________________________
# Representing variables and constants in LLVM source code
-
+
def repr_arg(self, arg):
if isinstance(arg, Constant):
if isinstance(arg.concretetype, lltype.Primitive):
- return primitive_to_str(arg.concretetype, arg.value)
+ return self.primitive_to_str(arg.concretetype, arg.value)
else:
node = self.obj2node.get(arg)
if node is None:
@@ -292,7 +301,7 @@
return self.obj2node[arg].ref
except KeyError:
if isinstance(arg, lltype.Primitive):
- return PRIMITIVES_TO_LLVM[arg]
+ return self.primitives[arg]
elif isinstance(arg, lltype.Ptr):
return self.repr_arg_type(arg.TO) + '*'
else:
@@ -311,7 +320,7 @@
" returns node and repr as tuple "
type_ = lltype.typeOf(value)
if isinstance(type_, lltype.Primitive):
- repr = primitive_to_str(type_, value)
+ repr = self.primitive_to_str(type_, value)
return None, "%s %s" % (self.repr_arg_type(type_), repr)
elif isinstance(type_, lltype.Ptr):
@@ -336,3 +345,24 @@
count = self._tmpcount
self._tmpcount += 1
return "%tmp." + str(count)
+
+ # __________________________________________________________
+ # Primitive stuff
+
+ def primitive_to_str(self, type_, value):
+ #XXX Need to watch for special float values (inf, 2E200)
+ if type_ is lltype.Bool:
+ repr = str(value).lower() #False --> false
+ elif type_ is lltype.Char:
+ repr = str(ord(value))
+ elif type_ is lltype.UniChar:
+ repr = str(ord(value))
+ else:
+ repr = str(value)
+ return repr
+
+ def get_machine_word(self):
+ return self.primitives[lltype.Signed]
+
+ def get_machine_uword(self):
+ return self.primitives[lltype.Unsigned]
Modified: pypy/dist/pypy/translator/llvm2/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/node.py (original)
+++ pypy/dist/pypy/translator/llvm2/node.py Fri Aug 12 01:31:53 2005
@@ -35,7 +35,7 @@
if hasattr(self, "_constructor_ref"):
raise TypeError, ("can only set constructor_ref once!"
" currently: %s" % (self._constructor_ref,))
- if " " in ref:
+ if " " in ref or "<" in ref:
ref = '"%s"' % (ref,)
self._constructor_ref = ref
return property(_get_ref, _set_ref)
Modified: pypy/dist/pypy/translator/llvm2/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/opwriter.py (original)
+++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 12 01:31:53 2005
@@ -96,6 +96,7 @@
if not meth:
msg = "operation %s not found" %(op.opname,)
self.codewriter.comment('XXX: Error: ' + msg)
+ # XXX commented out for testing
#assert meth is not None, msg
return
meth(op)
@@ -105,9 +106,12 @@
mult_val = self.db.repr_arg(op.args[0])
last_val = mult_val
try:
- operand = int(op.args[1].value)
- except:
- msg = 'XXX: Error: _generic_pow: Variable has no value'
+ value = "NO VALUE"
+ value = op.args[1].value
+ operand = int(value)
+ except Exception, exc:
+ msg = 'XXX: Error: _generic_pow: Variable '\
+ '%s - failed to convert to int %s' % (value, str(exc))
self.codewriter.comment(msg)
return
if operand < 1:
@@ -150,8 +154,11 @@
self.db.repr_arg(op.args[0]),
)
def int_neg(self, op):
- self._generic_neg(op, "0")
- uint_neg = int_neg #this is really generates, don't know why
+ self._generic_neg(op, "0")
+
+ #this is really generated, don't know why
+ # XXX rxe: Surely that cant be right?
+ uint_neg = int_neg
def float_neg(self, op):
self._generic_neg(op, "0.0")
@@ -200,7 +207,8 @@
self.db.repr_arg(op.args[0]),
tmpvar)
- def cast_primitive(self, op): #works for all primitives
+ def cast_primitive(self, op):
+ " works for all casts "
assert len(op.args) == 1
targetvar = self.db.repr_arg(op.result)
targettype = self.db.repr_arg_type(op.result)
@@ -256,7 +264,6 @@
self.codewriter.call_void(functionref, argrefs, argtypes)
def invoke(self, op):
- # XXX hack as per remove_voids()
op_args = [arg for arg in op.args
if arg.concretetype is not lltype.Void]
@@ -271,6 +278,7 @@
else:
msg = "exception raising operation %s not found" %(op.opname,)
self.codewriter.comment('XXX: Error: ' + msg)
+ # XXX commented out for testing
#assert functionref in extfunctions, msg
assert len(op_args) >= 1
@@ -416,7 +424,9 @@
("uint", index))
self.codewriter.load(targetvar, targettype, tmpvar)
else:
- self.codewriter.comment("***Skipping operation getfield()***") #XXX what if this the last operation of the exception block?
+ #XXX what if this the last operation of the exception block?
+ # XXX rxe: would a getfield() ever raise anyway???
+ self.codewriter.comment("***Skipping operation getfield()***")
def getsubstruct(self, op):
struct, structtype = self.db.repr_argwithtype(op.args[0])
@@ -470,7 +480,6 @@
valuevar = self.db.repr_arg(op.args[2])
valuetype = self.db.repr_arg_type(op.args[2])
- #XXX These should skip too if the case comes up
if valuetype != "void":
self.codewriter.getelementptr(tmpvar, arraytype, array,
("uint", 1), (indextype, index))
@@ -478,7 +487,6 @@
else:
self.codewriter.comment("***Skipping operation setarrayitem()***")
-
def getarraysize(self, op):
array, arraytype = self.db.repr_argwithtype(op.args[0])
tmpvar = self.db.repr_tmpvar()
Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/pyxwrapper.py (original)
+++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py Fri Aug 12 01:31:53 2005
@@ -1,15 +1,29 @@
+import sys
from pypy.translator.llvm2.log import log
from pypy.rpython import lltype
from pypy.translator.llvm2.genllvm import use_boehm_gc
log = log.pyrex
-PRIMITIVES_TO_C = {lltype.Signed: "int",
- lltype.Unsigned: "unsigned int",
- lltype.Bool: "char",
+PRIMITIVES_TO_C = {lltype.Bool: "char",
lltype.Float: "double",
lltype.Char: "char",
}
+# 32 bit platform
+if sys.maxint == 2**31-1:
+ PRIMITIVES_TO_C.update({
+ lltype.Signed: "int",
+ lltype.Unsigned: "unsigned int" })
+
+# 64 bit platform
+elif sys.maxint == 2**63-1:
+ PRIMITIVES_TO_C.update({
+ lltype.Signed: "long",
+ lltype.Unsigned: "unsigned long" })
+
+else:
+ assert False, "Unsupported platform"
+
def write_pyx_wrapper(funcgen, targetpath):
def c_declaration():
returntype = PRIMITIVES_TO_C[
Modified: pypy/dist/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/structnode.py (original)
+++ pypy/dist/pypy/translator/llvm2/structnode.py Fri Aug 12 01:31:53 2005
@@ -51,8 +51,10 @@
def __init__(self, db, struct):
super(StructVarsizeTypeNode, self).__init__(db, struct)
self.constructor_ref = "%%new.varsizestruct.%s" % (self.name)
- self.constructor_decl = "%s * %s(int %%len)" % \
- (self.ref, self.constructor_ref)
+ self.constructor_decl = "%s * %s(%s %%len)" % \
+ (self.ref,
+ self.constructor_ref,
+ self.db.get_machine_word())
def __str__(self):
return "<StructVarsizeTypeNode %r>" %(self.ref,)
@@ -79,7 +81,7 @@
assert isinstance(current, lltype.Array)
arraytype = self.db.repr_arg_type(current.OF)
# XXX write type info as a comment
- varsize.write_constructor(codewriter,
+ varsize.write_constructor(self.db, codewriter,
self.ref, self.constructor_decl, arraytype,
indices_to_array,
atomicmalloc=self.is_atomic())
Modified: pypy/dist/pypy/translator/llvm2/varsize.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/varsize.py (original)
+++ pypy/dist/pypy/translator/llvm2/varsize.py Fri Aug 12 01:31:53 2005
@@ -15,14 +15,15 @@
ret %array* %result
}"""
-def write_constructor(codewriter, ref, constructor_decl, elemtype,
+def write_constructor(db, codewriter, ref, constructor_decl, elemtype,
indices_to_array=(), atomicmalloc=False):
#varsized arrays and structs look like this:
#Array: {int length , elemtype*}
#Struct: {...., Array}
- # the following indices access the last element in the array
- elemindices = list(indices_to_array) + [("uint", 1), ("int", "%len")]
+ # the following indices access the last element in the array
+ lentype = db.get_machine_word()
+ elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")]
codewriter.openfunc(constructor_decl)
codewriter.getelementptr("%size", ref + "*", "null", *elemindices)
@@ -35,7 +36,7 @@
codewriter.getelementptr("%arraylength", ref + "*",
"%result",
*indices_to_array)
- codewriter.store("int", "%len", "%arraylength")
+ codewriter.store(lentype, "%len", "%arraylength")
codewriter.ret(ref + "*", "%result")
codewriter.closefunc()
More information about the Pypy-commit
mailing list