[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