[pypy-svn] r27654 - in pypy/dist/pypy/translator: c/test stackless stackless/test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed May 24 18:22:34 CEST 2006


Author: cfbolz
Date: Wed May 24 18:22:33 2006
New Revision: 27654

Modified:
   pypy/dist/pypy/translator/c/test/test_stackless.py
   pypy/dist/pypy/translator/stackless/test/test_depth.py
   pypy/dist/pypy/translator/stackless/transform.py
Log:
small optimization in stackless: don't safe state for tail calls. need to fix
some tests, because they were tail calls, so the stack-depth was wrong :-).
This makes pypy-c-stackless slightly smaller (125 kb less code).


Modified: pypy/dist/pypy/translator/c/test/test_stackless.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_stackless.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_stackless.py	Wed May 24 18:22:33 2006
@@ -62,7 +62,7 @@
         def f(n):
             g1()
             if n > 0:
-                res = f(n-1)
+                res = f(n-1) + 0 # make sure it is not a tail call
             else:
                 res = stack_frames_depth()
             g2(g1)
@@ -79,10 +79,10 @@
     def test_stack_withptr(self):
         def f(n):
             if n > 0:
-                res = f(n-1)
+                res, dummy = f(n-1)
             else:
-                res = stack_frames_depth(), 1
-            return res
+                res, dummy = stack_frames_depth(), 1
+            return res, dummy
 
         def fn():
             count0, _ = f(0)
@@ -96,10 +96,10 @@
         def f(n):
             if n > 0:
                 stack_frames_depth()
-                res = f(n-1)
+                res, dummy = f(n-1)
             else:
-                res = stack_frames_depth(), 1
-            return res
+                res, dummy = stack_frames_depth(), 1
+            return res, dummy
 
         def fn():
             count0, _ = f(0)
@@ -112,10 +112,10 @@
     def test_stackless_arguments(self):
         def f(n, d, t):
             if n > 0:
-                res = f(n-1, d, t)
+                a, b, c = f(n-1, d, t)
             else:
-                res = stack_frames_depth(), d, t
-            return res
+                a, b, c = stack_frames_depth(), d, t
+            return a, b, c
 
         def fn():
             count0, d, t = f(0, 5.5, (1, 2))

Modified: pypy/dist/pypy/translator/stackless/test/test_depth.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_depth.py	(original)
+++ pypy/dist/pypy/translator/stackless/test/test_depth.py	Wed May 24 18:22:33 2006
@@ -14,7 +14,7 @@
     def f(n):
         g1()
         if n > 0:
-            res = f(n-1)
+            res = f(n-1) + 0
         else:
             res = rstack.stack_frames_depth()
         g2(g1)
@@ -34,7 +34,8 @@
 def test_with_ptr():
     def f(n):
         if n > 0:
-            res = f(n-1)
+            res, dummy = f(n-1)
+            return (res, dummy)
         else:
             res = rstack.stack_frames_depth(), 1
         return res
@@ -53,7 +54,8 @@
 def test_manytimes():
     def f(n):
         if n > 0:
-            res = f(n-1)
+            res, dummy = f(n-1)
+            return (res, dummy)
         else:
             res = rstack.stack_frames_depth(), 1
         return res
@@ -72,7 +74,8 @@
 def test_arguments():
     def f(n, d, t):
         if n > 0:
-            res = f(n-1, d, t)
+            res, y, z = f(n-1, d, t)
+            return res, y, z
         else:
             res = rstack.stack_frames_depth(), d, t
         return res
@@ -95,3 +98,19 @@
 
     res = llinterp_stackless_function(fn)
     assert res == 1
+
+def test_eliminate_tail_calls():
+    # make sure that when unwinding the stack there are no frames saved
+    # for tail calls
+    def f(n):
+        if n > 0:
+            res = f(n-1)
+        else:
+            res = rstack.stack_frames_depth()
+        return res
+    def fn():
+        count0 = f(0)
+        count10 = f(10)
+        return count10 - count0
+    res = llinterp_stackless_function(fn)
+    assert res == 0

Modified: pypy/dist/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/transform.py	(original)
+++ pypy/dist/pypy/translator/stackless/transform.py	Wed May 24 18:22:33 2006
@@ -419,6 +419,15 @@
                     i += 1
                     continue
 
+                if (not stackless_op and i == len(block.operations) - 1 and
+                    len(block.exits) == 1 and
+                    block.exits[0].target is self.curr_graph.returnblock and
+                    (block.exits[0].args[0].concretetype is lltype.Void or 
+                     block.exits[0].args[0] is op.result)):
+#                    print "optimizing tail call %s in function %s" % (op, self.curr_graph.name)
+                    i += 1
+                    continue
+
                 if i == len(block.operations) - 1 \
                        and block.exitswitch == model.c_last_exception:
                     link = block.exits[0]



More information about the Pypy-commit mailing list