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

arigo at codespeak.net arigo at codespeak.net
Tue Dec 18 15:47:09 CET 2007


Author: arigo
Date: Tue Dec 18 15:47:08 2007
New Revision: 49889

Modified:
   pypy/dist/pypy/translator/backendopt/constfold.py
   pypy/dist/pypy/translator/backendopt/test/test_constfold.py
Log:
Another case for constfold: after an exitswitch on a variable,
we know in all links the value of that variable.  Two tests
showing when this can be useful (the second one is a common
occurrence in lltypesystem/rdict).


Modified: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Tue Dec 18 15:47:08 2007
@@ -234,11 +234,22 @@
 
 
 def constant_diffuse(graph):
+    count = 0
+    # after 'exitswitch vexit', replace 'vexit' with the corresponding constant
+    # if it also appears on the outgoing links
+    for block in graph.iterblocks():
+        vexit = block.exitswitch
+        if isinstance(vexit, Variable):
+            for link in block.exits:
+                if vexit in link.args:
+                    remap = {vexit: Constant(link.llexitcase,
+                                             vexit.concretetype)}
+                    link.args = [remap.get(v, v) for v in link.args]
+                    count += 1
     # if the same constants appear at the same positions in all links
     # into a block remove them from the links, remove the corresponding
     # input variables and introduce equivalent same_as at the beginning
     # of the block then try to fold the block further
-    count = 0
     for block, links in mkentrymap(graph).iteritems():
         if block is graph.startblock:
             continue

Modified: pypy/dist/pypy/translator/backendopt/test/test_constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_constfold.py	Tue Dec 18 15:47:08 2007
@@ -273,3 +273,47 @@
     assert graph.startblock.exits[1].target is graph.returnblock
     check_graph(graph, [10], 0, t)
     check_graph(graph, [42], 100, t)
+
+def test_knownswitch_after_exitswitch():
+    def fn(n):
+        cond = n > 10
+        if cond:
+            return cond + 5
+        else:
+            return cond + 17
+
+    graph, t = get_graph(fn, [int])
+    from pypy.translator.backendopt import removenoops
+    removenoops.remove_same_as(graph)
+    constant_fold_graph(graph)
+    if conftest.option.view:
+        t.view()
+    assert summary(graph) == {'int_gt': 1}
+    check_graph(graph, [2], 17, t)
+    check_graph(graph, [42], 6, t)
+
+def test_coalesce_exitswitchs():
+    def g(n):
+        return n > 5 and n < 20
+    def fn(n):
+        if g(n):
+            return 100
+        else:
+            return 0
+
+    graph, t = get_graph(fn, [int])
+    from pypy.translator.backendopt import removenoops, inline
+    inline.auto_inline_graphs(t, [graph], threshold=999)
+    removenoops.remove_same_as(graph)
+    constant_fold_graph(graph)
+    if conftest.option.view:
+        t.view()
+    # check that the graph starts with a condition (which should be 'n > 5')
+    # and that if this condition is false, it goes directly to 'return 0'.
+    assert summary(graph) == {'int_gt': 1, 'int_lt': 1}
+    assert len(graph.startblock.exits) == 2
+    assert graph.startblock.exits[0].exitcase == False
+    assert graph.startblock.exits[0].target is graph.returnblock
+    check_graph(graph, [2], 0, t)
+    check_graph(graph, [10], 100, t)
+    check_graph(graph, [42], 0, t)



More information about the Pypy-commit mailing list