[pypy-svn] r13601 - in pypy/dist/pypy/translator/llvm2: . test

hpk at codespeak.net hpk at codespeak.net
Sun Jun 19 14:28:28 CEST 2005


Author: hpk
Date: Sun Jun 19 14:28:27 2005
New Revision: 13601

Added:
   pypy/dist/pypy/translator/llvm2/structnode.py
Modified:
   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/test/test_genllvm.py
Log:
(cfbolz, hpk)

- added StructNode for - guess what -struct handling 

- added getfield/setfield and malloc support

- simple tuple test passes 

- some minor improvements and refactorings



Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py	Sun Jun 19 14:28:27 2005
@@ -14,12 +14,20 @@
     def indent(self, line): 
         self.append("        " + line) 
 
-    def label(self, name): 
+    def label(self, name):
         self.append("    %s:" % name)
 
-    def declare(self, decl): 
+    def structdef(self, name, typereprs):
+        self.append("%s = type { %s }" %(name, ", ".join(typereprs)))
+
+    def declare(self, decl):
         self.append("declare %s" %(decl,))
 
+    def startimpl(self):
+        self.append("")
+        self.append("implementation")
+        self.append("")
+
     def br_uncond(self, blockname): 
         self.indent("br label %%%s" %(blockname,))
 
@@ -56,5 +64,19 @@
         self.indent("%(targetvar)s = cast %(fromtype)s "
                         "%(fromvar)s to %(targettype)s" % locals())
 
+    def malloc(self, targetvar, type):
+        self.indent("%(targetvar)s = malloc %(type)s" % locals())
+
+    def getelementptr(self, targetvar, type, typevar, index):
+        self.indent("%(targetvar)s = getelementptr "
+                    "%(type)s %(typevar)s, int 0, uint %(index)s" % locals())
+
+    def load(self, targetvar, targettype, ptr):
+        self.indent("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals())
+
+    def store(self, valuetype, valuevar, ptr): 
+        self.indent("store %(valuetype)s %(valuevar)s, "
+                    "%(valuetype)s* %(ptr)s" % locals())
+
     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	Sun Jun 19 14:28:27 2005
@@ -1,5 +1,6 @@
 from pypy.translator.llvm2.log import log 
 from pypy.translator.llvm2.funcnode import FuncNode
+from pypy.translator.llvm2.structnode import StructNode 
 from pypy.rpython import lltype
 from pypy.objspace.flow.model import Block, Constant, Variable
 
@@ -13,6 +14,14 @@
         self._translator = translator
         self.obj2node = {}
         self._pendingsetup = []
+        self._tmpcount = 1
+
+    def addpending(self, key, node): 
+        assert key not in self.obj2node, (
+            "node with key %r already known!" %(key,))
+        self.obj2node[key] = node 
+        log("added to pending nodes:", node) 
+        self._pendingsetup.append(node) 
 
     def prepare_repr_arg(self, const_or_var):
         if const_or_var in self.obj2node:
@@ -20,15 +29,23 @@
         if isinstance(const_or_var, Constant):
             if isinstance(const_or_var.concretetype, lltype.Primitive):
                 pass
+                #log.prepare(const_or_var, "(is primitive)") 
             else:
-                node = FuncNode(self, const_or_var) 
-                self.obj2node[const_or_var] = node
-                log("added to pending nodes:", node) 
-                self._pendingsetup.append(node) 
+                self.addpending(const_or_var, FuncNode(self, const_or_var)) 
+        else:
+            log.prepare.ignore(const_or_var) 
 
     def prepare_repr_arg_type(self, type_):
-        if not isinstance(type_, lltype.Primitive):
-            log.XXX("need to prepare typeref")
+        if type_ in self.obj2node:
+            return
+        if isinstance(type_, lltype.Primitive):
+            pass
+        elif isinstance(type_, lltype.Ptr): 
+            self.prepare_repr_arg_type(type_.TO)
+        elif isinstance(type_, lltype.Struct): 
+            self.addpending(type_, StructNode(self, type_))
+        else:     
+            log.XXX("need to prepare typerepr", type_)
 
     def prepare_arg(self, const_or_var):
         log.prepare(const_or_var)
@@ -52,10 +69,26 @@
         return self.obj2node[arg].ref
 
     def repr_arg_type(self, arg):
-        return PRIMITIVES_TO_LLVM[arg.concretetype]
+        if isinstance(arg, (Constant, Variable)): 
+            arg = arg.concretetype 
+        try:
+            return self.obj2node[arg].ref 
+        except KeyError: 
+            if isinstance(arg, lltype.Primitive):
+                return PRIMITIVES_TO_LLVM[arg]
+            elif isinstance(arg, lltype.Ptr):
+                return self.repr_arg_type(arg.TO) + '*'
+            else: 
+                raise TypeError("cannot represent %r" %(arg,))
 
     def repr_arg_multi(self, args):
         return [self.repr_arg(arg) for arg in args]
 
     def repr_arg_type_multi(self, args):
         return [self.repr_arg_type(arg) for arg in args]
+
+    def repr_tmpvar(self): 
+        count = self._tmpcount 
+        self._tmpcount += 1
+        return "%tmp." + str(count) 
+        

Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py	Sun Jun 19 14:28:27 2005
@@ -1,6 +1,7 @@
 import py
 from pypy.objspace.flow.model import Block, Constant, Variable, Link
 from pypy.objspace.flow.model import flatten, mkentrymap, traverse
+from pypy.rpython import lltype
 from pypy.translator.llvm2.cfgtransform import prepare_graph
 from pypy.translator.llvm2.log import log 
 log = log.funcnode
@@ -15,7 +16,7 @@
                                    db._translator)
 
     def __str__(self):
-        return "<FuncNode ref=%s>" %(self.ref,)
+        return "<FuncNode %r>" %(self.ref,)
     
     def setup(self):
         log("setup", self)
@@ -42,6 +43,8 @@
         result += "(%s)" % ", ".join(args)
         return result 
 
+    # ______________________________________________________________________
+    # main entry points from genllvm 
     def writedecl(self, codewriter): 
         codewriter.declare(self.getdecl())
 
@@ -66,6 +69,9 @@
                 self.write_block(codewriter, block)
         codewriter.closefunc()
 
+    # ______________________________________________________________________
+    # writing helpers for entry points
+
     def write_block(self, codewriter, block):
         self.write_block_phi_nodes(codewriter, block)
         self.write_block_operations(codewriter, block)
@@ -171,10 +177,33 @@
                              argtypes)
 
     def malloc(self, op): 
-        log.XXX("malloc not emitted") 
+        targetvar = self.db.repr_arg(op.result) 
+        arg = op.args[0]
+        assert (isinstance(arg, Constant) and 
+                isinstance(arg.value, lltype.Struct))
+        type = "%" + arg.value._name 
+        self.codewriter.malloc(targetvar, type) 
 
     def getfield(self, op): 
-        log.XXX("getfield not emitted") 
+        tmpvar = self.db.repr_tmpvar()
+        type = self.db.repr_arg_type(op.args[0]) 
+        typevar = self.db.repr_arg(op.args[0]) 
+        fieldnames = list(op.args[0].concretetype.TO._names)
+        index = fieldnames.index(op.args[1].value)
+        self.codewriter.getelementptr(tmpvar, type, typevar, index)
+
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        self.codewriter.load(targetvar, targettype, tmpvar)
 
     def setfield(self, op): 
-        log.XXX("setfield not emitted") 
+        tmpvar = self.db.repr_tmpvar()
+        type = self.db.repr_arg_type(op.args[0]) 
+        typevar = self.db.repr_arg(op.args[0]) 
+        fieldnames = list(op.args[0].concretetype.TO._names)
+        index = fieldnames.index(op.args[1].value)
+        self.codewriter.getelementptr(tmpvar, type, typevar, index)
+
+        valuevar = self.db.repr_arg(op.args[2]) 
+        valuetype = self.db.repr_arg_type(op.args[2])
+        self.codewriter.store(valuetype, valuevar, tmpvar) 

Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py	Sun Jun 19 14:28:27 2005
@@ -26,6 +26,7 @@
     log.debug(db.obj2node)
     for node in dbobjects:
         node.writedecl(codewriter) 
+    codewriter.startimpl() 
     for node in dbobjects:
         node.writeimpl(codewriter)
     

Added: pypy/dist/pypy/translator/llvm2/structnode.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm2/structnode.py	Sun Jun 19 14:28:27 2005
@@ -0,0 +1,34 @@
+import py
+from pypy.objspace.flow.model import Block, Constant, Variable, Link
+from pypy.translator.llvm2.log import log 
+log = log.structnode 
+
+class StructNode(object):
+    _issetup = False 
+
+    def __init__(self, db, struct): 
+        self.db = db
+        self.struct = struct 
+        self.ref = "%" + struct._name 
+
+    def __str__(self):
+        return "<StructNode %r>" %(self.ref,)
+    
+    def setup(self):
+        log.XXX("setup", self)
+        self._issetup = True
+
+    # ______________________________________________________________________
+    # entry points from genllvm 
+    #
+    def writedecl(self, codewriter): 
+        assert self._issetup 
+        struct = self.struct
+        l = []
+        for fieldname in struct._names:
+            type_ = getattr(struct, fieldname)
+            l.append(self.db.repr_arg_type(type_))
+        codewriter.structdef(self.ref, l) 
+
+    def writeimpl(self, codewriter):
+        assert self._issetup 

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	Sun Jun 19 14:28:27 2005
@@ -78,7 +78,7 @@
     f = compile_function(call_ackermann, [int, int])
     assert f(0, 2) == 3
     
-def XXXtest_tuple_getitem(): 
+def test_tuple_getitem(): 
     def list_getitem(i): 
         l = (1,2,i)
         return l[1]



More information about the Pypy-commit mailing list