[pypy-commit] pypy ssa-flow: Renovate SSA_to_SSI() and use it instead of fixeggblocks().

rlamy noreply at buildbot.pypy.org
Wed Nov 12 19:43:07 CET 2014


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: ssa-flow
Changeset: r74486:ee2bf8c11af5
Date: 2013-08-15 04:21 +0100
http://bitbucket.org/pypy/pypy/changeset/ee2bf8c11af5/

Log:	Renovate SSA_to_SSI() and use it instead of fixeggblocks().

	This will allow build_flow() to use the SSA paradigm.

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -7,6 +7,7 @@
 import __builtin__
 
 from rpython.tool.error import source_lines
+from rpython.translator.backendopt.ssa import SSA_to_SSI
 from rpython.rlib import rstackovf
 from rpython.flowspace.argument import CallSpec
 from rpython.flowspace.model import (Constant, Variable, Block, Link,
@@ -86,27 +87,7 @@
                 if isinstance(w_value, Variable):
                     w_value.rename(name)
             del block.framestate     # memory saver
-
-    # EggBlocks reuse the variables of their previous block,
-    # which is deemed not acceptable for simplicity of the operations
-    # that will be performed later on the flow graph.
-    for link in list(graph.iterlinks()):
-        block = link.target
-        if isinstance(block, EggBlock):
-            if (not block.operations and len(block.exits) == 1 and
-                link.args == block.inputargs):   # not renamed
-                # if the variables are not renamed across this link
-                # (common case for EggBlocks) then it's easy enough to
-                # get rid of the empty EggBlock.
-                link2 = block.exits[0]
-                link.args = list(link2.args)
-                link.target = link2.target
-                assert link2.exitcase is None
-            else:
-                mapping = {}
-                for a in block.inputargs:
-                    mapping[a] = Variable(a)
-                block.renamevariables(mapping)
+    SSA_to_SSI(graph)
 
 # ____________________________________________________________
 
diff --git a/rpython/translator/backendopt/ssa.py b/rpython/translator/backendopt/ssa.py
--- a/rpython/translator/backendopt/ssa.py
+++ b/rpython/translator/backendopt/ssa.py
@@ -141,11 +141,9 @@
         return entrymap
 
 def variables_created_in(block):
-    result = {}
-    for v in block.inputargs:
-        result[v] = True
+    result = set(block.inputargs)
     for op in block.operations:
-        result[op.result] = True
+        result.add(op.result)
     return result
 
 
@@ -158,28 +156,34 @@
     'graph_or_blocks' can be a graph, or just a dict that lists some blocks
     from a graph, as follows: {block: reachable-from-outside-flag}.
     """
+    seen = set()
+    for link in graph_or_blocks.iterlinks():
+        mapping = {}
+        seen.update(link.args)
+        for arg in link.target.inputargs:
+            if arg in seen and isinstance(arg, Variable):
+                mapping[arg] = Variable(arg)
+        link.target.renamevariables(mapping)
+
     entrymap = mkinsideentrymap(graph_or_blocks)
     builder = DataFlowFamilyBuilder(graph_or_blocks)
     variable_families = builder.get_variable_families()
     del builder
 
     pending = []     # list of (block, var-used-but-not-defined)
-
     for block in entrymap:
         variables_created = variables_created_in(block)
-        variables_used = {}
+        variables_used = set()
         for op in block.operations:
-            for v in op.args:
-                variables_used[v] = True
-        variables_used[block.exitswitch] = True
+            variables_used.update(op.args)
+        variables_used.add(block.exitswitch)
         for link in block.exits:
-            for v in link.args:
-                variables_used[v] = True
+            variables_used.update(link.args)
 
         for v in variables_used:
-            if isinstance(v, Variable):
-                if v not in variables_created:
-                    pending.append((block, v))
+            if (isinstance(v, Variable) and v not in variables_created and
+                    v._name not in ('last_exception_', 'last_exc_value_')):
+                pending.append((block, v))
 
     while pending:
         block, v = pending.pop()
@@ -190,8 +194,7 @@
         for w in variables_created:
             w_rep = variable_families.find_rep(w)
             if v_rep is w_rep:
-                # 'w' is in the same family as 'v', so we can simply
-                # reuse its value for 'v'
+                # 'w' is in the same family as 'v', so we can reuse it
                 block.renamevariables({v: w})
                 break
         else:


More information about the pypy-commit mailing list