[pypy-svn] r10601 - in pypy/dist/pypy/translator/llvm: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Apr 14 03:48:23 CEST 2005


Author: cfbolz
Date: Thu Apr 14 03:48:22 2005
New Revision: 10601

Modified:
   pypy/dist/pypy/translator/llvm/class.ll
   pypy/dist/pypy/translator/llvm/classrepr.py
   pypy/dist/pypy/translator/llvm/funcrepr.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/list.c
   pypy/dist/pypy/translator/llvm/list_template.ll
   pypy/dist/pypy/translator/llvm/representation.py
   pypy/dist/pypy/translator/llvm/seqrepr.py
   pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
   pypy/dist/pypy/translator/llvm/test/test_genllvm.py
   pypy/dist/pypy/translator/llvm/typerepr.py
Log:
Implemeted pickling of global class instances, lists, tuples to code that creates them.

Modified: pypy/dist/pypy/translator/llvm/class.ll
==============================================================================
--- pypy/dist/pypy/translator/llvm/class.ll	(original)
+++ pypy/dist/pypy/translator/llvm/class.ll	Thu Apr 14 03:48:22 2005
@@ -52,4 +52,23 @@
 internal sbyte %std.unwind() {
 entry:
 	unwind
-}
\ No newline at end of file
+}
+
+;simple builtin functions
+internal sbyte %std.chr(int %a) {
+        %r = cast int %a to sbyte
+        ret sbyte %r
+}
+
+internal int %std.ord(sbyte %c) {
+        %r = cast sbyte %c to int
+        ret int %r
+}
+
+;XXXX
+internal int %std.ord(%std.list.sbyte* %c) {
+	%c = call sbyte %std.getitem(%std.list.sbyte* %c, int 0)
+        %r = cast sbyte %c to int
+        ret int %r
+}
+

Modified: pypy/dist/pypy/translator/llvm/classrepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/classrepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/classrepr.py	Thu Apr 14 03:48:22 2005
@@ -9,6 +9,7 @@
 from pypy.translator.llvm import llvmbc
 
 from pypy.translator.llvm.representation import debug, LLVMRepr
+from pypy.translator.llvm.representation import TmpVariableRepr
 from pypy.translator.llvm.typerepr import TypeRepr, PointerTypeRepr
 from pypy.translator.llvm.funcrepr import FunctionRepr, BoundMethodRepr
 from pypy.translator.llvm.funcrepr import VirtualMethodRepr
@@ -83,6 +84,9 @@
         for key, attr in self.classdef.attrs.items():
             if debug:
                 print key, attr, attr.sources, attr.s_value,
+            if isinstance(attr.s_value, annmodel.SomeImpossibleValue):
+                print "--> removed"
+                continue
             if len(attr.sources) != 0:
                 func = self.classdef.cls.__dict__[attr.name]
                 meth.append((key, func))
@@ -139,7 +143,7 @@
             PointerTypeRepr("%std.class*", self.gen), l_func)
         lblock.getelementptr(l_tmp, l_target, [0, 0])
         lblock.instruction("store %%std.class* %s, %s" %
-                           (self.objectname, l_tmp.typed_name()))
+                           (self.objectname, l_tmp.typed_name()))        
         init = None
         for cls in self.classdef.getmro():
             if "__init__" in cls.attrs:
@@ -193,9 +197,15 @@
         if not isinstance(args[1], Constant):
             raise CompileError,"setattr called with non-constant: %s" % args[1]
         if args[1].value in self.attr_num:
+            l_type = self.l_attrs_types[self.attr_num[args[1].value] - 1]
             l_args0 = self.gen.get_repr(args[0])
             l_value = self.gen.get_repr(args[2])
             self.dependencies.update([l_args0, l_value])
+            if l_value.llvmtype() != l_type.typename():
+                l_cast = self.gen.get_local_tmp(l_type, l_func)
+                self.dependencies.add(l_cast)
+                lblock.cast(l_cast, l_value)
+                l_value = l_cast
             l_pter = self.gen.get_local_tmp(
                 PointerTypeRepr(l_value.llvmtype(), self.gen), l_func)
             lblock.getelementptr(l_pter, l_args0,
@@ -312,3 +322,47 @@
         lblock.getelementptr(l_tmp, l_args0, [0, 0])
         lblock.load(l_target, l_tmp)
     
+
+class InstanceRepr(LLVMRepr):
+    def get(obj, gen):
+        if isinstance(obj, Constant):
+            ann = gen.annotator.binding(obj)
+            print "InstanceRepr.get: ", obj, ann, ann.__class__
+            if isinstance(ann, annmodel.SomeInstance):
+                return InstanceRepr(obj, ann.classdef, gen)
+    get = staticmethod(get)
+
+    def __init__(self, obj, classdef, gen):
+        if debug:
+            print "InstanceRepr: ", obj, classdef
+        self.obj = obj
+        self.gen = gen
+        self.type = gen.get_repr(classdef)
+        self.dependencies = sets.Set([self.type])
+        self.name = gen.get_global_tmp(obj.value.__class__.__name__ + ".inst")
+
+    def setup(self):
+        self.l_attrib_values = []
+        for attr in self.type.attributes:
+            s_a = self.gen.get_repr(getattr(self.obj.value, attr.name))
+            self.l_attrib_values.append(s_a)
+        self.dependencies.update(self.l_attrib_values)
+        self.definition = self.name + " = internal global %s {%s" % \
+                          (self.llvmtype()[:-1], self.type.typed_name())
+        if len(self.l_attrib_values) == 0:
+            self.definition += "}"
+        else:
+            attrs = ", ".join([at.typename() + " " + av.llvmname()
+                               for at, av in zip(self.type.l_attrs_types,
+                                                 self.l_attrib_values)])
+            self.definition += ", " + attrs + "}"
+
+    def get_globals(self):
+        return self.definition
+
+    def __getattr__(self, name):
+        if name.startswith("op_"):
+            return getattr(self.type, "t_" + name, None)
+        else:
+            raise AttributeError, ("InstanceRepr instance has no attribute %s"
+                                   % repr(name))

Modified: pypy/dist/pypy/translator/llvm/funcrepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcrepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/funcrepr.py	Thu Apr 14 03:48:22 2005
@@ -7,6 +7,7 @@
 from pypy.objspace.flow.model import last_exception, last_exc_value
 from pypy.objspace.flow.model import traverse, checkgraph
 from pypy.annotation import model as annmodel
+from pypy.annotation.builtin import BUILTIN_ANALYZERS
 from pypy.translator.llvm import llvmbc
 from pypy.translator.unsimplify import remove_double_links
 
@@ -23,7 +24,7 @@
                  "inplace_mod", "inplace_pow", "inplace_lshift",
                  "inplace_rshift", "inplace_and", "inplace_or", "inplace_xor",
                  "contains", "newlist", "newtuple", "alloc_and_set",
-                 "issubtype", "type"]
+                 "issubtype", "type", "ord"]
 
 C_SIMPLE_TYPES = {annmodel.SomeChar: "char",
                   annmodel.SomeString: "char*",
@@ -34,8 +35,11 @@
 
 class BuiltinFunctionRepr(LLVMRepr):
     def get(obj, gen):
-        if isinstance(obj, Constant) and \
-           isinstance(gen.annotator.binding(obj), annmodel.SomeBuiltin):
+        if isinstance(obj, Constant):
+            print "BuiltinFunctionRepr", obj.value
+        if (isinstance(obj, Constant) and
+            (obj in BUILTIN_ANALYZERS or
+             isinstance(gen.annotator.binding(obj), annmodel.SomeBuiltin))):
             return BuiltinFunctionRepr(obj.value.__name__, gen)
         elif isinstance(obj, annmodel.SomeBuiltin):
             name = obj.analyser.__name__.replace("method_", "")

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Thu Apr 14 03:48:22 2005
@@ -37,6 +37,8 @@
         return obj.value
     if isinstance(obj, annmodel.SomeInstance):
         return obj.classdef.cls
+    if isinstance(obj, list):
+        return id(obj)
     return obj
 
 class LLVMGenerator(object):
@@ -106,7 +108,6 @@
                 print "->exists already:", self.llvm_reprs[get_key(obj)]
             return self.llvm_reprs[get_key(obj)]
         for cl in self.repr_classes:
-            #XXXXXX: Got
             try:
                 obj.__class__
             except AttributeError:
@@ -175,3 +176,9 @@
             yield l_dep1
     yield l_repr
 
+
+## from pypy.translator.test.rpystone import *
+## t = Translator(Proc0)
+## a = t.annotate([int])
+## t.view()
+## f = llvmcompile(t)

Modified: pypy/dist/pypy/translator/llvm/list.c
==============================================================================
--- pypy/dist/pypy/translator/llvm/list.c	(original)
+++ pypy/dist/pypy/translator/llvm/list.c	Thu Apr 14 03:48:22 2005
@@ -157,13 +157,14 @@
     return nlist;
 }
 
-void inplace_add(struct list* a, struct list* b) {
+struct list* inplace_add(struct list* a, struct list* b) {
     struct item** newdata = malloc(sizeof(struct item*) * (a->length + b->length));
     copy(a->data, newdata, a->length);
     copy(b->data, newdata + a->length, b->length);
     a->length +=  b->length;
     free(a->data);
     a->data = newdata;
+    return a;
 }
 
 void append(struct list* a, struct item* value) {
@@ -223,4 +224,4 @@
 	hi -= 1;
     }
 }
- 
+

Modified: pypy/dist/pypy/translator/llvm/list_template.ll
==============================================================================
--- pypy/dist/pypy/translator/llvm/list_template.ll	(original)
+++ pypy/dist/pypy/translator/llvm/list_template.ll	Thu Apr 14 03:48:22 2005
@@ -353,7 +353,7 @@
 	ret %std.list.%(name)s* %tmp.0
 }
 
-internal void %std.inplace_add(%std.list.%(name)s* %a, %std.list.%(name)s* %b) {
+internal %std.list.%(name)s* %std.inplace_add(%std.list.%(name)s* %a, %std.list.%(name)s* %b) {
 entry:
 	%tmp.2 = getelementptr %std.list.%(name)s* %a, int 0, uint 0
 	%tmp.3 = load uint* %tmp.2
@@ -397,7 +397,7 @@
 	store uint %tmp.7, uint* %tmp.2
 	free %(item)s* %tmp.12
 	store %(item)s* %tmp.0, %(item)s** %tmp.11
-	ret void
+	ret %std.list.%(name)s* %a
 }
 
 internal void %std.append(%std.list.%(name)s* %a, %(item)s %value) {

Modified: pypy/dist/pypy/translator/llvm/representation.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/representation.py	(original)
+++ pypy/dist/pypy/translator/llvm/representation.py	Thu Apr 14 03:48:22 2005
@@ -190,7 +190,7 @@
 
     def __init__(self, obj, gen):
         if debug:
-            print "StringRepr: %s" % obj
+            print "StringRepr: %s, %s length: %i" % (obj, repr(obj), len(obj))
         self.s = obj
         self.gen = gen
         self.glvar1 = gen.get_global_tmp("StringRepr")
@@ -203,7 +203,8 @@
 
     def get_globals(self):
         d = {"len": len(self.s), "gv1": self.glvar1, "gv2": self.glvar2,
-             "type": self.type.typename_wo_pointer(), "string": self.s}
+             "type": self.type.typename_wo_pointer(),
+             "string": str(repr(self.s)[1:-1].replace("\\x", "\\"))}
         s = """%(gv1)s = internal global [%(len)i x sbyte] c"%(string)s"
 %(gv2)s = internal global %(type)s {uint %(len)i,\
 sbyte* getelementptr ([%(len)i x sbyte]* %(gv1)s, uint 0, uint 0)}"""

Modified: pypy/dist/pypy/translator/llvm/seqrepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/seqrepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/seqrepr.py	Thu Apr 14 03:48:22 2005
@@ -11,6 +11,58 @@
 from pypy.translator.llvm.funcrepr import BoundMethodRepr
 
 
+debug = False
+
+class ListRepr(LLVMRepr):
+    def get(obj, gen):
+        if obj.__class__ == list:
+            return ListRepr(obj, gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, l, gen):
+        self.list = l
+        self.gen = gen
+        self.type = self.gen.get_repr(
+            gen.annotator.bookkeeper.immutablevalue(l))
+        self.dependencies = sets.Set([self.type])
+        self.name = self.gen.get_global_tmp("std.list.inst")
+        self.definition = self.name
+        self.definition += " = internal global %s {uint %i, %s* null}" % \
+                           (self.type.typename()[:-1], len(self.list),
+                            self.type.l_itemtype.typename())
+
+    def setup(self):
+        self.l_items = [self.gen.get_repr(item) for item in self.list]
+        self.dependencies.update(self.l_items)
+
+    def get_globals(self):
+        return self.definition
+
+    def collect_init_code(self, lblock, l_func):
+        l_itemtype = self.type.l_itemtype
+        gen = self.gen
+        l_tmp = self.gen.get_local_tmp(PointerTypeRepr(
+            "[%d x %s]" % (len(self.list), l_itemtype.typename()), gen),
+                                  l_func)
+        self.dependencies.add(l_tmp)
+        lblock.malloc(l_tmp)
+        for i, l_item in enumerate(self.l_items):
+            l_ptr = self.gen.get_local_tmp(
+                PointerTypeRepr(l_itemtype.typename(), gen), l_func)
+            self.dependencies.add(l_ptr)
+            lblock.getelementptr(l_ptr, l_tmp, [0, i])
+            lblock.store(l_item, l_ptr)
+        l_from = self.gen.get_local_tmp(
+            PointerTypeRepr("%s" % l_itemtype.typename(), gen), l_func)
+        l_to = self.gen.get_local_tmp(
+            PointerTypeRepr("%s*" % l_itemtype.typename(), gen), l_func)
+        self.dependencies.update([l_from, l_to])
+        lblock.getelementptr(l_from, l_tmp, [0, 0])
+        lblock.getelementptr(l_to, self, [0, 1])
+        lblock.store(l_from, l_to)
+            
+
 class ListTypeRepr(TypeRepr):
     l_listtypes = {}
     def get(obj, gen):
@@ -79,6 +131,8 @@
             type_ = gen.annotator.binding(obj)
             if isinstance(type_, annmodel.SomeTuple):
                 return TupleRepr(obj, gen)
+        elif obj.__class__ == tuple:
+            return TupleRepr(Constant(obj), gen)
         return None
     get = staticmethod(get)
 
@@ -116,9 +170,17 @@
 
 
 class TupleTypeRepr(TypeRepr):
+    l_tuple_types = {}
     def get(obj, gen):
         if isinstance(obj, annmodel.SomeTuple):
-            return TupleTypeRepr(obj, gen)
+            l_tt = TupleTypeRepr(obj, gen)
+            #XXXXXXXX: Ugly as hell but neccessary: It prevents that two
+            #different tuples with same "signature" get different TupleTypeRepr
+            #also slightly unsafe, but well...
+            if (l_tt.typename(), gen) in TupleTypeRepr.l_tuple_types:
+                return TupleTypeRepr.l_tuple_types[(l_tt.typename(), gen)]
+            TupleTypeRepr.l_tuple_types[(l_tt.typename(), gen)] = l_tt
+            return l_tt
         return None
     get = staticmethod(get)
 

Modified: pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	Thu Apr 14 03:48:22 2005
@@ -45,7 +45,7 @@
 #float snippets
 
 def float_f1(x):
-    return x + 1.0
+    return x + 1.2
 
 def float_int_bool(x):
     return x * (2 + True)
@@ -178,6 +178,22 @@
     d.set_range()
     return d.a[i]
 
+class GGG(object):
+    pass
+
+ggg = GGG()
+ggg.a = 36
+ggg.b = (1, 2, 3)
+ggg.c = [1, 2, 3]
+
+def global_instance(x):
+    previous = ggg.a
+    previous1 = ggg.c[-1]
+    ggg.c.append(x)
+    d = ggg.b[1]
+    ggg.a = x
+    return previous + d + previous1
+
 #simple inheritance snippets
 class AAA(object):
     def __init__(self):

Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py	Thu Apr 14 03:48:22 2005
@@ -124,7 +124,7 @@
 
     def test_float_f1(self):
         f = compile_function(llvmsnippet.float_f1, [float])
-        assert f(1.0) == 2.0
+        assert f(1.0) == 2.2
 
     def test_float_int_bool(self):
         f = compile_function(llvmsnippet.float_int_bool, [float])
@@ -238,6 +238,12 @@
         f = compile_function(llvmsnippet.merge_classes, [bool])
         assert f(True) == 1
         assert f(False) == 2
+
+    def test_global_instance(self):
+        f = compile_function(llvmsnippet.global_instance, [int])
+        assert f(-1) == 41
+        for i in range(20):
+            assert f(i) == 2 * i
     
 class TestString(object):
     def setup_method(self, method):

Modified: pypy/dist/pypy/translator/llvm/typerepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/typerepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/typerepr.py	Thu Apr 14 03:48:22 2005
@@ -85,6 +85,11 @@
         l_func.dependencies.update(l_args)
         lblock.spaceop(l_target, "add", l_args)
 
+    def t_op_inplace_mul(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "mul", l_args)
+
 
 class IntTypeRepr(TypeRepr):
     def get(obj, gen):
@@ -165,6 +170,8 @@
     def typename(self):
         return self.type + "*"
 
+
+#This should only be used as the return value for "void" functions
 class ImpossibleValueRepr(TypeRepr):
     def get(obj, gen):
         if obj.__class__ is annmodel.SomeImpossibleValue:



More information about the Pypy-commit mailing list