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

rxe at codespeak.net rxe at codespeak.net
Wed Jul 6 13:36:12 CEST 2005


Author: rxe
Date: Wed Jul  6 13:36:10 2005
New Revision: 14326

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/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_genllvm.py
Log:
Rationalisation of how prebuilt constants interact with the database.
 


Modified: pypy/dist/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/arraynode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/arraynode.py	Wed Jul  6 13:36:10 2005
@@ -2,7 +2,6 @@
 from pypy.rpython import lltype
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.node import LLVMNode
-from pypy.objspace.flow.model import Constant
 from pypy.translator.llvm2 import varsize 
 import itertools  
 log = log.structnode
@@ -53,44 +52,29 @@
                                   fromtype)
 
 class ArrayNode(LLVMNode):
-    _issetup = False 
+    _issetup = True 
     def __init__(self, db, value):
+        assert isinstance(lltype.typeOf(value), lltype.Array)
         self.db = db
         self.value = value
-        self.arraytype = value._TYPE.OF
-        self.ref = "%%arrayinstance.%s.%s" % (value._TYPE.OF, nextnum())
+        self.arraytype = lltype.typeOf(value).OF
+        self.ref = "%%arrayinstance.%s.%s" % (self.arraytype, nextnum())
+        if isinstance(self.arraytype, lltype.Ptr):
+            for item in self.value.items:
+                self.db.addptrvalue(item)
 
     def __str__(self):
         return "<ArrayNode %r>" %(self.ref,)
-
-    def setup(self):
-        for item in self.value.items:
-            if not isinstance(self.arraytype, lltype.Primitive):
-                # Create a dummy constant hack XXX
-                self.db.prepare_arg(Constant(item, self.arraytype))
-        self._issetup = True
-
-    def value_helper(self, value):        
-        """ This should really be pushed back to the database??? XXX """
-        if not isinstance(self.arraytype, lltype.Primitive):
-            # Create a dummy constant hack XXX
-            value = self.db.repr_arg(Constant(value, self.arraytype))
-        else:
-            if isinstance(value, str) and len(value) == 1:
-                value = ord(value)                    
-            value = str(value)
-        return value
     
-    def getall(self):
+    def typeandvalue(self):
         """ Returns the type and value for this node. """
         items = self.value.items
-        typeval = self.db.repr_arg_type(self.arraytype)
         arraylen = len(items)
 
-        type_ = "{ int, [%s x %s] }" % (arraylen, typeval)        
-        arrayvalues = ["%s %s" % (typeval,
-                                  self.value_helper(v)) for v in items]
+        typeval = self.db.repr_arg_type(self.arraytype)
 
+        type_ = "{ int, [%s x %s] }" % (arraylen, typeval)        
+        arrayvalues = ["%s %s" % self.db.reprs_constant(v) for v in items]
         value = "int %s, [%s x %s] [ %s ]" % (arraylen,
                                               arraylen,
                                               typeval,
@@ -101,5 +85,5 @@
     # entry points from genllvm
 
     def writeglobalconstants(self, codewriter):
-        type_, values = self.getall()
+        type_, values = self.typeandvalue()
         codewriter.globalinstance(self.ref, type_, values)

Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py	Wed Jul  6 13:36:10 2005
@@ -30,7 +30,7 @@
         self.append("    %s:" % name)
 
     def globalinstance(self, name, type, data):
-        self.append("%s = internal constant %s {%s}" % (name, type, data))
+        self.append("%s = constant %s {%s}" % (name, type, data))
 
     def structdef(self, name, typereprs):
         self.append("%s = type { %s }" %(name, ", ".join(typereprs)))

Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py	(original)
+++ pypy/dist/pypy/translator/llvm2/database.py	Wed Jul  6 13:36:10 2005
@@ -53,8 +53,56 @@
     def __init__(self, translator): 
         self._translator = translator
         self.obj2node = NormalizingDict() 
+        self.ptr2nodevalue = {} 
         self._pendingsetup = []
         self._tmpcount = 1
+
+    def addptrvalue(self, ptrvalue):
+        value = ptrvalue._obj
+        node = self.create_constant_node(value)
+        self.ptr2nodevalue[value] = self.create_constant_node(value)        
+
+    def getptrnode(self, ptrvalue):
+        return self.ptr2nodevalue[ptrvalue._obj]
+
+    def getptrref(self, ptrvalue):
+        return self.ptr2nodevalue[ptrvalue._obj].ref
+
+    def reprs_constant(self, value):        
+        type_ = lltype.typeOf(value)
+        if isinstance(type_, lltype.Primitive):
+            if isinstance(value, str) and len(value) == 1:
+                res = ord(value)                    
+            res = str(value)
+        elif isinstance(type_, lltype.Ptr):
+            res = self.getptrref(value)
+        #elif isinstance(type_, lltype.Array) or isinstance(type_, lltype.Struct):
+        #XXX    res = self.value.typeandvalue()
+        else:
+            assert False, "not supported XXX"
+        return self.repr_arg_type(type_), res
+
+    def create_constant_node(self, value):
+        type_ = lltype.typeOf(value)
+        node = None
+        if isinstance(type_, lltype.FuncType):
+            
+            if value._callable \
+                   and not hasattr(value, 'graph'):
+                log('EXTERNAL FUNCTION' + str(dir(value)))
+            else:
+                node = FuncNode(self, value)
+
+        elif isinstance(type_, lltype.Struct):
+            if type_._arrayfld:
+                node = StructVarsizeNode(self, value)
+            else:
+                node = StructNode(self, value)
+                    
+        elif isinstance(type_, lltype.Array):
+            node = ArrayNode(self, value)
+        assert node is not None, "%s not supported" % lltype.typeOf(value)
+        return node
         
     def addpending(self, key, node): 
         assert key not in self.obj2node, (
@@ -69,37 +117,19 @@
         self._pendingsetup and to self.obj2node"""
         if const_or_var in self.obj2node:
             return
+
         if isinstance(const_or_var, Constant):
-            
             ct = const_or_var.concretetype
-            while isinstance(ct, lltype.Ptr):
-                ct = ct.TO
-            
-            if isinstance(ct, lltype.FuncType):
-                if const_or_var.value._obj._callable and not hasattr(const_or_var.value._obj, 'graph'):
-                    log('EXTERNAL FUNCTION' + str(dir(const_or_var.value._obj)))
-                else:
-                    self.addpending(const_or_var, FuncNode(self, const_or_var))
-            else:
-                value = const_or_var.value
-                while hasattr(value, "_obj"):
-                    value = value._obj
-
-                if isinstance(ct, lltype.Struct):
-                    if ct._arrayfld:
-                        self.addpending(const_or_var, StructVarsizeNode(self, value))
-                    else:
-                        self.addpending(const_or_var, StructNode(self, value))
-
-                elif isinstance(ct, lltype.Array):
-                    self.addpending(const_or_var, ArrayNode(self, value))
-
-                elif isinstance(ct, lltype.Primitive):
-                    log.prepare(const_or_var, "(is primitive)")
-                else:
-                    log.XXX("not sure what to do about %s(%s)" % (ct, const_or_var))
+
+            if isinstance(ct, lltype.Primitive):
+                log.prepare(const_or_var, "(is primitive)")
+                return
+
+            assert isinstance(ct, lltype.Ptr), "Preperation of non primitive and non pointer" 
+            value = const_or_var.value._obj            
+            self.addpending(const_or_var, self.create_constant_node(value))
         else:
-            log.prepare(const_or_var, type(const_or_var)) #XXX dont checkin
+            log.prepare(const_or_var, type(const_or_var))
 
     def prepare_repr_arg_multi(self, args):
         for const_or_var in args:
@@ -144,7 +174,7 @@
 
     def getobjects(self, subset_types=None):
         res = []
-        for v in self.obj2node.values():
+        for v in self.obj2node.values() + self.ptr2nodevalue.values():
             if subset_types is None or isinstance(v, subset_types):
                 res.append(v)
         return res

Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py	Wed Jul  6 13:36:10 2005
@@ -37,11 +37,11 @@
 class FuncNode(LLVMNode):
     _issetup = False 
 
-    def __init__(self, db, const_ptr_func):
+    def __init__(self, db, value):
         self.db = db
-        self.const_ptr_func = const_ptr_func
-        self.ref = "%" + const_ptr_func.value._obj._name
-        self.graph = const_ptr_func.value._obj.graph 
+        self.value = value
+        self.ref = "%" + value._name
+        self.graph = value.graph 
         remove_same_as(self.graph) 
         remove_double_links(self.db._translator, self.graph) 
         
@@ -67,10 +67,10 @@
         codewriter.declare(self.getdecl())
 
     def writeimpl(self, codewriter):
-        _callable = self.const_ptr_func.value._obj._callable
+        _callable = self.value._callable
         for func, extfuncinfo in extfunctable.iteritems():  # precompute a dict?
             if _callable is extfuncinfo.ll_function:
-                log('skipped output of external function %s' % self.const_ptr_func.value._obj._name)
+                log('skipped output of external function %s' % self.value._name)
                 return
 
         assert self._issetup 

Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py	Wed Jul  6 13:36:10 2005
@@ -1,6 +1,9 @@
 from os.path import exists
 use_boehm_gc = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a')
 
+#XXXTmp
+use_boehm_gc = False
+
 import py
 from pypy.translator.llvm2 import build_llvm_module
 from pypy.translator.llvm2.database import Database 

Modified: pypy/dist/pypy/translator/llvm2/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/node.py	(original)
+++ pypy/dist/pypy/translator/llvm2/node.py	Wed Jul  6 13:36:10 2005
@@ -26,6 +26,10 @@
         return property(_get_ref, _set_ref)
     constructor_ref = constructor_ref()
 
+
+    def setup(self):
+        pass
+
     # __________________ before "implementation" ____________________
     def writedatatypedecl(self, codewriter):
         """ write out declare names of data types 

Modified: pypy/dist/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/structnode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/structnode.py	Wed Jul  6 13:36:10 2005
@@ -1,5 +1,4 @@
 import py
-from pypy.objspace.flow.model import Block, Constant, Variable, Link
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.node import LLVMNode
 from pypy.translator.llvm2 import varsize
@@ -74,6 +73,9 @@
             self.ref, self.constructor_decl, arraytype, 
             indices_to_array)
 
+
+#XXX Everything downwind of here is experimental code
+
 def cast_global(toptr, from_, name):
     s = "cast(%s* getelementptr (%s* %s, int 0) to %s)" % (from_,
                                                            from_,
@@ -88,36 +90,28 @@
         self.db = db
         self.value = value
         self.ref = "%%stinstance.%s.%s" % (value._TYPE._name, nextnum())
+        for name in self.value._TYPE._names_without_voids():
+            T = self.value._TYPE._flds[name]
+            assert T is not lltype.Void
+            if isinstance(T, lltype.Ptr):
+                self.db.addptrvalue(getattr(self.value, name))
 
     def __str__(self):
         return "<StructNode %r>" %(self.ref,)
 
     def setup(self):
-        for name in self.value._TYPE._names_without_voids():
-            T = self.value._TYPE._flds[name]
-            assert T is not lltype.Void
-            if not isinstance(T, lltype.Primitive):
-                value = getattr(self.value, name)
-                # Create a dummy constant hack XXX
-                c = Constant(value, T)
-                self.db.prepare_arg(c)
-                
         self._issetup = True
 
-    def getall(self):
+    def typeandvalue(self):
         res = []
         type_ = self.value._TYPE
         for name in type_._names_without_voids():
             T = type_._flds[name]
             value = getattr(self.value, name)
-            if not isinstance(T, lltype.Primitive):
-                # Create a dummy constant hack XXX
-                c = Constant(value, T)
-
-                # Needs some sanitisation
-                x = self.db.obj2node[c]
-                value = self.db.repr_arg(c)
-                t, v = x.getall()
+            if isinstance(T, lltype.Ptr):
+                x = self.db.getptrnode(value)
+                value = self.db.getptrref(value)
+                t, v = x.typeandvalue()
                 value = cast_global(self.db.repr_arg_type(T), t, value)
                 
             else:
@@ -129,14 +123,16 @@
         return typestr, values
     
     def writeglobalconstants(self, codewriter):
-        type_, values = self.getall()
+        type_, values = self.typeandvalue()
         codewriter.globalinstance(self.ref, type_, values)
+
+#XXX Everything downwind of here is very experimental code and no tests pass
                 
 class StructVarsizeNode(StructNode):
     def __str__(self):
         return "<StructVarsizeNode %r>" %(self.ref,)
 
-    def getall(self):
+    def typeandvalue(self):
         res = []
         type_ = self.value._TYPE
         for name in type_._names_without_voids()[:-1]:
@@ -156,7 +152,7 @@
         value = getattr(self.value, name)
         c = Constant(value, T)
         x = self.db.obj2node[c]
-        t, v = x.getall()
+        t, v = x.typeandvalue()
 
         #value = self.db.repr_arg(c)
         value = cast_global(self.db.repr_arg_type(T), t, "{%s}" % v)

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	Wed Jul  6 13:36:10 2005
@@ -12,7 +12,7 @@
 from pypy.rpython.rtyper import RPythonTyper
 from pypy.rpython.rarithmetic import r_uint
 
-#py.log.setconsumer("genllvm", py.log.STDOUT)
+py.log.setconsumer("genllvm", py.log.STDOUT)
 py.log.setconsumer("genllvm database prepare", None)
 
 
@@ -114,7 +114,7 @@
     f = compile_function(ops, [int])
     assert f(1) == 1
     assert f(2) == 2
-
+    
 def test_while_loop():
     def factorial(i):
         r = 1



More information about the Pypy-commit mailing list