[pypy-svn] r33169 - in pypy/dist/pypy/translator/backendopt: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Oct 11 16:12:59 CEST 2006


Author: cfbolz
Date: Wed Oct 11 16:12:57 2006
New Revision: 33169

Modified:
   pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
   pypy/dist/pypy/translator/backendopt/test/test_all.py
   pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
Log:
fix a bug in merge_if_blocks: if two of the checked values are the same, then
checkgraph complains. In this case drop the additional block.


Modified: pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/merge_if_blocks.py	(original)
+++ pypy/dist/pypy/translator/backendopt/merge_if_blocks.py	Wed Oct 11 16:12:57 2006
@@ -20,7 +20,7 @@
         return False
     return True
 
-def merge_chain(chain, checkvar, varmap):
+def merge_chain(chain, checkvar, varmap, graph):
     def get_new_arg(var_or_const):
         if isinstance(var_or_const, Constant):
             return var_or_const
@@ -28,6 +28,7 @@
     firstblock, case = chain[0]
     firstblock.operations = firstblock.operations[:-1]
     firstblock.exitswitch = checkvar 
+    values = {}
     links = []
     default = chain[-1][0].exits[0]
     default.exitcase = "default"
@@ -35,6 +36,11 @@
     default.prevblock = firstblock
     default.args = [get_new_arg(arg) for arg in default.args]
     for block, case in chain:
+        if case.value in values:
+            log.WARNING("unreachable code with value %s in graph %s" % (
+                        case.value, graph))
+            continue
+        values[case.value] = True
         link = block.exits[1]
         links.append(link)
         link.exitcase = case.value
@@ -97,11 +103,13 @@
             break
     else:
         return False
-    log("merging blocks in %s" % (graph.name, ))
-    merge_chain(chain, checkvars[0], varmap)
+    merge_chain(chain, checkvars[0], varmap, graph)
     checkgraph(graph)
     return True
 
 def merge_if_blocks(graph):
+    merge = False
     while merge_if_blocks_once(graph):
-        pass
+        merge = True
+    if merge:
+        log("merging blocks in %s" % (graph.name, ))

Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py	Wed Oct 11 16:12:57 2006
@@ -6,11 +6,15 @@
 from pypy.objspace.flow.model import Constant
 from pypy.annotation import model as annmodel
 from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.rarithmetic import intmask
+from pypy import conftest
 
 def translateopt(func, sig, **optflags):
     t = TranslationContext()
     t.buildannotator().build_types(func, sig)
     t.buildrtyper().specialize()
+    if conftest.option.view:
+        t.view()
     backend_optimizations(t, **optflags)
     return t
 
@@ -166,3 +170,23 @@
     interp = LLInterpreter(t.rtyper)
     res = interp.eval_graph(graphof(t, myfunc), [10])
     assert res == 5
+
+def test_range_iter():
+    def fn(start, stop, step):
+        res = 0
+        if step == 0:
+            if stop >= start:
+                r = range(start, stop, 1)
+            else:
+                r = range(start, stop, -1)
+        else:
+            r = range(start, stop, step)
+        for i in r:
+            res = res * 51 + i
+        return res
+    t = translateopt(fn, [int, int, int], merge_if_blocks_to_switch=True)
+    interp = LLInterpreter(t.rtyper)
+    for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
+        assert interp.eval_graph(graphof(t, fn), args) == intmask(fn(*args))
+
+

Modified: pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py	Wed Oct 11 16:12:57 2006
@@ -160,3 +160,26 @@
     merge_if_blocks(graph)
     assert blocknum == len(list(graph.iterblocks()))
 
+def test_same_cases():
+    def fn(x):
+        if x == 42:
+            r = 1
+        elif x == 42:
+            r = 2
+        else:
+            r = 3
+        return r
+    t = TranslationContext()
+    a = t.buildannotator()
+    a.build_types(fn, [int])
+    rtyper = t.buildrtyper()
+    rtyper.specialize()
+    backend_optimizations(t, merge_if_blocks_to_switch=True)
+    graph = tgraphof(t, fn)
+    assert len(graph.startblock.exits) == 2
+    interp = LLInterpreter(rtyper)
+    for i in [42, 43]:
+        expected = fn(i)
+        actual = interp.eval_graph(graph, [i])
+        assert actual == expected
+



More information about the Pypy-commit mailing list