[pypy-commit] pypy faster-set-of-iterator: do unrolling the old-fashioned way. Write a test that it works.

cfbolz noreply at buildbot.pypy.org
Mon Jul 15 11:49:43 CEST 2013


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: faster-set-of-iterator
Changeset: r65399:ad1ca28aad79
Date: 2013-07-11 22:13 +0200
http://bitbucket.org/pypy/pypy/changeset/ad1ca28aad79/

Log:	do unrolling the old-fashioned way. Write a test that it works.

diff --git a/pypy/interpreter/unpack.py b/pypy/interpreter/unpack.py
--- a/pypy/interpreter/unpack.py
+++ b/pypy/interpreter/unpack.py
@@ -40,20 +40,21 @@
 
 
 unpack_into_driver = jit.JitDriver(name='unpack_into',
-                                   greens=['unroll', 'unpackcls', 'w_type'],
+                                   greens=['unpackcls', 'w_type'],
                                    reds=['unpack_target', 'w_iterator'])
 
 def generic_unpack_into(w_iterable, space, unpack_target, unroll=False):
+    if unroll:
+        return generic_unpack_into_unroll(w_iterable, space, unpack_target)
+    else:
+        return generic_unpack_into_jitdriver(w_iterable, space, unpack_target)
+
+def generic_unpack_into_jitdriver(w_iterable, space, unpack_target):
     w_iterator = space.iter(w_iterable)
     w_type = space.type(w_iterator)
     unpackcls = type(unpack_target)
     while True:
-        if not unroll:
-            unpack_into_driver.can_enter_jit(w_type=w_type, unroll=unroll,
-                                             w_iterator=w_iterator,
-                                             unpack_target=unpack_target,
-                                             unpackcls=unpackcls)
-        unpack_into_driver.jit_merge_point(w_type=w_type, unroll=unroll,
+        unpack_into_driver.jit_merge_point(w_type=w_type,
                                            w_iterator=w_iterator,
                                            unpack_target=unpack_target,
                                            unpackcls=unpackcls)
@@ -65,3 +66,15 @@
             break  # done
         unpack_target.append(w_item)
 
+ at jit.unroll_safe
+def generic_unpack_into_unroll(w_iterable, space, unpack_target):
+    w_iterator = space.iter(w_iterable)
+    while True:
+        try:
+            w_item = space.next(w_iterator)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break  # done
+        unpack_target.append(w_item)
+
diff --git a/pypy/module/pypyjit/test/test_unpacktracing.py b/pypy/module/pypyjit/test/test_unpacktracing.py
--- a/pypy/module/pypyjit/test/test_unpacktracing.py
+++ b/pypy/module/pypyjit/test/test_unpacktracing.py
@@ -97,11 +97,30 @@
             return len(target.items_w) + res
         assert f(4) == 210
 
-        # hack
-        from rpython.jit.metainterp import compile
-        class A(object):
-            view = viewloops = False
-        compile.option = A()
         result = self.meta_interp(f, [4], listops=True, backendopt=True, listcomp=True)
         assert result == 210
         self.check_trace_count(2)
+
+    def test_unroll(self):
+        unpack_into_driver = jit.JitDriver(greens=[], reds='auto')
+        def f(i):
+            l = [W_Int(x) for x in range(i)]
+            l.append(W_Int(i))
+
+            w_l = W_List(l)
+            res = 0
+            for i in range(100):
+                unpack_into_driver.jit_merge_point()
+                target = unpack.FixedSizeUnpackTarget(space, len(l))
+                if i < 0:
+                    w_l.unpack_into(space, target)
+                else:
+                    w_l.unpack_into(space, target, unroll=True)
+                res += len(target.items_w)
+            return res
+        assert f(4) == 500
+
+        result = self.meta_interp(f, [4], listops=True, backendopt=True, listcomp=True)
+        assert result == 500
+        self.check_resops(getarrayitem_gc=10, setarrayitem_gc=10,
+                call_may_force=0)


More information about the pypy-commit mailing list