Author: Remi Meier <remi.me...@gmail.com>
Branch: stmgc-c8
Changeset: r80997:c4bb2166366b
Date: 2015-11-27 12:56 +0100
http://bitbucket.org/pypy/pypy/changeset/c4bb2166366b/

Log:    do optimal evaluation order for forward flow analysis

diff --git a/rpython/translator/backendopt/dataflow.py 
b/rpython/translator/backendopt/dataflow.py
--- a/rpython/translator/backendopt/dataflow.py
+++ b/rpython/translator/backendopt/dataflow.py
@@ -36,7 +36,17 @@
         raise NotImplementedError("abstract base class")
 
 
-
+def postorder_block_list(graph):
+    visited = set()
+    blocks = []
+    def dfs_recurse(block):
+        visited.add(block)
+        for link in block.exits:
+            if link.target not in visited:
+                dfs_recurse(link.target)
+        blocks.append(block)
+    dfs_recurse(graph.startblock)
+    return blocks
 
 
 class AbstractForwardDataFlowAnalysis(AbstractDataFlowAnalysis):
@@ -86,18 +96,16 @@
 
         #
         # iterate:
-        # todo: ordered set? reverse post-order?
-        blocks.remove(graph.startblock)
-        pending = collections.deque(blocks)
-        pending.append(graph.startblock)
+        # todo: ordered set?
+        pending = collections.deque(reversed(postorder_block_list(graph)))
         while pending:
-            block = pending.pop()
+            block = pending.popleft()
             if self._update_in_state_of(block, entrymap, in_states, 
out_states):
                 block_out = self.transfer_function(block, in_states[block])
                 if block_out != out_states[block]:
                     out_states[block] = block_out
                     for link in block.exits:
                         if link.target not in pending:
-                            pending.appendleft(link.target)
+                            pending.append(link.target)
         #
         return in_states, out_states
diff --git a/rpython/translator/backendopt/test/test_dataflow.py 
b/rpython/translator/backendopt/test/test_dataflow.py
--- a/rpython/translator/backendopt/test/test_dataflow.py
+++ b/rpython/translator/backendopt/test/test_dataflow.py
@@ -1,6 +1,7 @@
 import random
 from rpython.tool.algo.unionfind import UnionFind
-from rpython.translator.backendopt.dataflow import 
AbstractForwardDataFlowAnalysis
+from rpython.translator.backendopt.dataflow import (
+    AbstractForwardDataFlowAnalysis, postorder_block_list)
 
 import pytest
 
@@ -85,3 +86,42 @@
     assert len(sfa.seen) == 5
     assert ins[g.startblock] == sfa.entry_state(None)
     assert outs[g.returnblock] == sfa.entry_state(None)
+
+
+def test_postorder_block_list():
+    def f(x):
+        pass
+    t = TranslationContext()
+    g = t.buildflowgraph(f)
+    pobl = postorder_block_list(g)
+    assert len(set(pobl)) == 2 # start & return
+
+    def f2(x):
+        if x:
+            x=x+1
+        else:
+            x=x+2
+        return x
+    t = TranslationContext()
+    g = t.buildflowgraph(f2)
+    pobl = postorder_block_list(g)
+    assert len(pobl[0].exits) == 0
+    assert len(pobl[1].exits) == 1
+    assert len(pobl[2].exits) == 1
+    assert len(pobl[3].exits) == 2
+    assert len(set(pobl)) == 4
+
+
+def test_postorder_block_list2():
+    def f(x):
+        if x < 0:
+            while x:
+                pass
+            return x
+        else:
+            while x:
+                if x-1:
+                    return x
+    t = TranslationContext()
+    g = t.buildflowgraph(f)
+    assert len(set(postorder_block_list(g))) == 5
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to