[pypy-svn] r35194 - in pypy/dist/pypy: objspace/flow/test rlib

arigo at codespeak.net arigo at codespeak.net
Fri Dec 1 12:41:48 CET 2006


Author: arigo
Date: Fri Dec  1 12:41:45 2006
New Revision: 35194

Modified:
   pypy/dist/pypy/objspace/flow/test/test_unroll.py
   pypy/dist/pypy/rlib/unroll.py
Log:
Fix a combinatorical explosion when unrolling loops with "if"
statements.  Done by caching the _unroller SpecTags, instead
of making fresh ones even for the same indices.


Modified: pypy/dist/pypy/objspace/flow/test/test_unroll.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/test/test_unroll.py	(original)
+++ pypy/dist/pypy/objspace/flow/test/test_unroll.py	Fri Dec  1 12:41:45 2006
@@ -1,3 +1,4 @@
+import operator
 from pypy.objspace.flow.test.test_objspace import Base
 from pypy.rlib.unroll import unrolling_zero, unrolling_iterable
 
@@ -38,3 +39,28 @@
         graph = self.codetest(f)
         ops = self.all_operations(graph)
         assert ops == {'setattr': 3}
+
+    def test_unroll_ifs(self):
+        operations = unrolling_iterable([operator.lt,
+                                         operator.le,
+                                         operator.eq,
+                                         operator.ne,
+                                         operator.gt,
+                                         operator.ge])
+        def accept(n):
+            "stub"
+        def f(x, y):
+            for op in operations:
+                if accept(op):
+                    op(x, y)
+
+        graph = self.codetest(f)
+        ops = self.all_operations(graph)
+        assert ops == {'simple_call': 6,
+                       'is_true': 6,
+                       'lt': 1,
+                       'le': 1,
+                       'eq': 1,
+                       'ne': 1,
+                       'gt': 1,
+                       'ge': 1}

Modified: pypy/dist/pypy/rlib/unroll.py
==============================================================================
--- pypy/dist/pypy/rlib/unroll.py	(original)
+++ pypy/dist/pypy/rlib/unroll.py	Fri Dec  1 12:41:45 2006
@@ -43,12 +43,13 @@
 
     def __init__(self, iterable):
         self._items = list(iterable)
+        self._head = _unroller(self._items)
 
     def __iter__(self):
         return iter(self._items)
 
     def get_unroller(self):
-        return _unroller(self._items)
+        return self._head
 
 
 class _unroller(SpecTag):
@@ -56,8 +57,10 @@
     def __init__(self, items, i=0):
         self._items = items
         self._i = i
+        self._next = None
 
     def step(self):
         v = self._items[self._i]
-        next = _unroller(self._items, self._i+1)
-        return v, next
+        if self._next is None:
+            self._next = _unroller(self._items, self._i+1)
+        return v, self._next


More information about the pypy-svn mailing list