[pypy-svn] rev 2103 - in pypy/trunk/src/pypy/translator: . test

sanxiyn at codespeak.net sanxiyn at codespeak.net
Tue Oct 28 06:44:13 CET 2003


Author: sanxiyn
Date: Tue Oct 28 06:44:12 2003
New Revision: 2103

Modified:
   pypy/trunk/src/pypy/translator/annotation.py
   pypy/trunk/src/pypy/translator/gencl.py
   pypy/trunk/src/pypy/translator/test/test_cltrans.py
   pypy/trunk/src/pypy/translator/transform.py
Log:
range and slice for gencl!

gencl
* typemap: list -> vector
* op not/is_true: list -> (zerop (length...
* prelude: python-slice, python-range
* builtin_map: range -> python-range
* op getslice: python-slice (with subseq)
* for convinience: cur_annset

test_cltrans
* slice test "half_of_n" working!

transform
* transform_slice, as usual

annotation
* simplify_hooks is dead
* if index is slice, arg and result is of same seq type

XXX
* GenCL.reflow is very probably wrong.
* There seems to be no simple way to add annotation and
propagate it once after annotation is built. If I'm wrong,
please correct me.

All those annotation stuffs make it possible to infer from
  x = range(n)
  y = x[1:]
that y is a list. Check half_of_n.lisp in a session directory.
Above code is followed by "if y:", and typecase is not emitted.


Modified: pypy/trunk/src/pypy/translator/annotation.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annotation.py	(original)
+++ pypy/trunk/src/pypy/translator/annotation.py	Tue Oct 28 06:44:12 2003
@@ -10,7 +10,6 @@
 
     def __init__(self, flowgraph):
         self.flowgraph = flowgraph
-        self.simplify_hooks = []
 
     def build_types(self, input_arg_types):
         input_ann = AnnotationSet()
@@ -65,8 +64,6 @@
 
     def simplify(self):
         self.simplify_calls()
-        for hook in self.simplify_hooks:
-            hook(self)
 
     #__________________________________________________
 
@@ -134,6 +131,18 @@
     def consider_op_newslice(self,op,annotations):
         annotations.set_type(op.result, slice)
 
+    def consider_op_getitem(self, op, annotations):
+        arg1,arg2 = op.args
+        type1 = annotations.get_type(arg1)
+        type2 = annotations.get_type(arg2)
+        if type1 in (list, tuple) and type2 is slice:
+            annotations.set_type(op.result, type1)
+
+    # XXX: this shouldn't be here...
+    def consider_op_getslice(self, op, annotations):
+        tp = annotations.get_type(op.args[0])
+        annotations.set_type(op.result, tp)
+
     def consider_const(self,to_var,const,annotations):
         if getattr(const, 'dummy', False):
             return   # undefined local variables

Modified: pypy/trunk/src/pypy/translator/gencl.py
==============================================================================
--- pypy/trunk/src/pypy/translator/gencl.py	(original)
+++ pypy/trunk/src/pypy/translator/gencl.py	Tue Oct 28 06:44:12 2003
@@ -65,6 +65,7 @@
         table = {
             (bool,): "(not %s)",
             (int,): "(zerop %s)",
+            (list,): "(zerop (length %s))",
         }
         self.gen.emit_typecase(table, arg1)
         print "))"
@@ -75,6 +76,7 @@
         table = {
             (bool,): "%s",
             (int,): "(not (zerop %s))",
+            (list,): "(not (zerop (length %s)))",
         }
         self.gen.emit_typecase(table, arg1)
         print ")"
@@ -109,6 +111,7 @@
         print "(setq", s(result), "(funcall", s(iterator), "))"
     builtin_map = {
         pow: "expt",
+        range: "python-range",
     }
     def op_simple_call(self):
         func = self.args[0]
@@ -119,12 +122,21 @@
         if func not in self.builtin_map:
             self.op_default()
             return
+        # XXX: generalize this later
+        if func is range:
+            annset = self.gen.cur_annset()
+            annset.set_type(self.result, list)
+            self.gen.reflow()
         s = self.str
         args = self.args[1:]
         print "(setq", s(self.result), "(", self.builtin_map[func],
         for arg in args:
             print s(arg),
         print "))"
+    def op_getslice(self):
+        s = self.str
+        result, (seq, start, end) = self.result, self.args
+        print "(setq", s(result), "(python-slice", s(seq), s(start), s(end), "))"
 
 
 class GenCL:
@@ -136,8 +148,14 @@
     def annotate(self, input_arg_types):
         ann = Annotator(self.fun)
         ann.build_types(input_arg_types)
+        ann.simplify()
         transform_graph(ann)
         self.ann = ann
+    def cur_annset(self):
+        return self.ann.annotated[self.cur_block]
+    def reflow(self):
+        # XXX: I know, I know. This is WRONG. -- sanxiyn
+        self.ann.build_annotations(self.cur_annset())
     def str(self, obj):
         if isinstance(obj, Variable):
             return obj.name
@@ -247,10 +265,11 @@
         bool: "boolean",
         int: "fixnum",
         type(''): "string", # hack, 'str' is in the namespace!
+        list: "vector",
     }
     def emit_typecase(self, table, *args):
         argreprs = tuple(map(self.str, args))
-        annset = self.ann.annotated[self.cur_block]
+        annset = self.cur_annset()
         argtypes = tuple(map(annset.get_type, args))
         if argtypes in table:
             trans = table[argtypes]
@@ -279,4 +298,17 @@
       (if (< i (length seq))
           (let ((v (elt seq i))) (incf i) (list v t))
           (list nil nil)))))
+(defun python-slice (seq start end)
+  (let ((l (length seq)))
+    (if (not start) (setf start 0))
+    (if (not end) (setf end l))
+    (if (minusp start) (incf start l))
+    (if (minusp end) (incf end l))
+    (subseq seq start end)))
+; temporary
+(defun python-range (end)
+  (let ((a (make-array end)))
+    (loop for i below end
+          do (setf (elt a i) i))
+    a))
 """

Modified: pypy/trunk/src/pypy/translator/test/test_cltrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_cltrans.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_cltrans.py	Tue Oct 28 06:44:12 2003
@@ -103,5 +103,9 @@
         cl_builtinusage = make_cl_func(t.builtinusage)
         self.assertEquals(cl_builtinusage(), 4)
 
+    def test_slice(self):
+        cl_half = make_cl_func(t.half_of_n)
+        self.assertEquals(cl_half(10), 5)
+
 if __name__ == '__main__':
     test.main()

Modified: pypy/trunk/src/pypy/translator/transform.py
==============================================================================
--- pypy/trunk/src/pypy/translator/transform.py	(original)
+++ pypy/trunk/src/pypy/translator/transform.py	Tue Oct 28 06:44:12 2003
@@ -24,6 +24,24 @@
                                     (new_op,) +
                                     operations[i+2:])
 
+def transform_slice(self):
+    for block, ann in self.annotated.iteritems():
+        operations = block.operations
+        n_op = len(operations)
+        for i in range(0, n_op-1):
+            op1 = operations[i]
+            op2 = operations[i+1]
+            if (op1.opname == 'newslice' and
+                ann.get_type(op1.args[2]) is type(None) and
+                op2.opname == 'getitem' and
+                op1.result is op2.args[1]):
+                new_op = SpaceOperation('getslice',
+                                         (op2.args[0], op1.args[0], op1.args[1]),
+                                         op2.result)
+                block.operations = (operations[:i] +
+                                    (new_op,) +
+                                    operations[i+2:])
+
 def transform_graph(ann):
-    ann.simplify_hooks.append(transform_allocate)
-    ann.simplify()
+    transform_allocate(ann)
+    transform_slice(ann)


More information about the Pypy-commit mailing list