[pypy-svn] r17822 - in pypy/dist/pypy/translator/backendopt: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 24 13:36:31 CEST 2005
Author: arigo
Date: Sat Sep 24 13:36:27 2005
New Revision: 17822
Modified:
pypy/dist/pypy/translator/backendopt/ssa.py
pypy/dist/pypy/translator/backendopt/test/test_ssa.py
Log:
Rewrote the data_flow_families() algorithm, which seems to consume a lot of
time.
Made up a couple of tests for ssa.py.
Modified: pypy/dist/pypy/translator/backendopt/ssa.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/ssa.py (original)
+++ pypy/dist/pypy/translator/backendopt/ssa.py Sat Sep 24 13:36:27 2005
@@ -8,33 +8,47 @@
all following variables where the value is just passed unmerged into the
next block.
"""
- entrymaplist = mkentrymap(graph).items()
+
+ # Build a list of "unification opportunities": for each block and each 'n',
+ # an "opportunity" is the list of the block's nth input variable plus
+ # the nth output variable from each of the incoming links.
+ opportunities = []
+ for block, links in mkentrymap(graph).items():
+ if block is graph.startblock:
+ continue
+ assert links
+ for n, inputvar in enumerate(block.inputargs):
+ vars = [inputvar]
+ for link in links:
+ var = link.args[n]
+ if not isinstance(var, Variable):
+ break
+ vars.append(var)
+ else:
+ # if no Constant found in the incoming links
+ opportunities.append(vars)
+
+ # An "opportunitiy" that lists exactly two distinct variables means that
+ # the two variables can be unified. We maintain the unification status in
+ # 'variable_families'. When variables are unified, it might reduce the
+ # number of distinct variables and thus open other "opportunities" for
+ # unification.
progress = True
variable_families = UnionFind()
-
- # group variables by families; a family of variables will be identified.
while progress:
progress = False
- for block, links in entrymaplist:
- if block is graph.startblock:
- continue
- assert links
- for i in range(len(block.inputargs)):
- # list of possible vars that can arrive in i'th position
- v1 = block.inputargs[i]
- v1 = variable_families.find_rep(v1)
- inputs = {v1: True}
- key = []
- for link in links:
- v = link.args[i]
- if not isinstance(v, Variable):
- break
- v = variable_families.find_rep(v)
- inputs[v] = True
- else:
- if len(inputs) == 2:
- variable_families.union(*inputs)
- progress = True
+ pending_opportunities = []
+ for vars in opportunities:
+ repvars = [variable_families.find_rep(v1) for v1 in vars]
+ repvars = dict.fromkeys(repvars).keys()
+ if len(repvars) > 2:
+ # cannot unify now, but maybe later?
+ pending_opportunities.append(repvars)
+ elif len(repvars) == 2:
+ # unify!
+ variable_families.union(*repvars)
+ progress = True
+ opportunities = pending_opportunities
return variable_families
def SSI_to_SSA(graph):
Modified: pypy/dist/pypy/translator/backendopt/test/test_ssa.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_ssa.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_ssa.py Sat Sep 24 13:36:27 2005
@@ -1,2 +1,52 @@
+from pypy.translator.backendopt.ssa import *
+from pypy.translator.translator import Translator
+from pypy.objspace.flow.model import flatten, Block
-# XXX write a test!
+
+def test_data_flow_families():
+ def snippet_fn(xx, yy):
+ while yy > 0:
+ if 0 < xx:
+ yy = yy - xx
+ else:
+ yy = yy + xx
+ return yy
+ t = Translator(snippet_fn)
+ graph = t.getflowgraph()
+ operations = []
+ for block in flatten(graph):
+ if isinstance(block, Block):
+ operations += block.operations
+
+ variable_families = data_flow_families(graph)
+
+ # we expect to find xx only once:
+ v_xx = variable_families.find_rep(graph.getargs()[0])
+ found = 0
+ for op in operations:
+ if op.opname in ('add', 'sub', 'lt'):
+ assert variable_families.find_rep(op.args[1]) == v_xx
+ found += 1
+ assert found == 3
+
+
+def test_SSI_to_SSA():
+ def snippet_fn(v1, v2, v3):
+ if v1: # v4 = is_true(v1)
+ while v3: # v5 = is_true(v3)
+ pass
+ passed_over = 0
+ else:
+ v6 = snippet_fn(v3, v2, v1) # v6 = simple_call(v3, v2, v1)
+ passed_over = v6
+ v7 = passed_over # v7 = inputarg
+ return v7+v1 # v8 = add(v7, v1)
+
+ t = Translator(snippet_fn)
+ SSI_to_SSA(t.getflowgraph())
+ allvars = []
+ for block in flatten(t.getflowgraph()):
+ if isinstance(block, Block):
+ allvars += [v.name for v in block.getvariables()]
+ # see comments above for where the 8 remaining variables are expected to be
+ assert len(dict.fromkeys(allvars)) == 8
More information about the Pypy-commit
mailing list