[pypy-svn] r13599 - pypy/dist/pypy/translator

arigo at codespeak.net arigo at codespeak.net
Sun Jun 19 13:17:55 CEST 2005


Author: arigo
Date: Sun Jun 19 13:17:53 2005
New Revision: 13599

Added:
   pypy/dist/pypy/translator/lltransform.py
      - copied, changed from r13590, pypy/dist/pypy/translator/llvm2/cfgtransform.py
Log:
Started a module to regroup post-rtyper optimizations on low-level
graphs.  Contains llvm2's remove_same_as() and an experimental transformation
that turns the graphs from SSI to SSA (see docstring).


Copied: pypy/dist/pypy/translator/lltransform.py (from r13590, pypy/dist/pypy/translator/llvm2/cfgtransform.py)
==============================================================================
--- pypy/dist/pypy/translator/llvm2/cfgtransform.py	(original)
+++ pypy/dist/pypy/translator/lltransform.py	Sun Jun 19 13:17:53 2005
@@ -1,8 +1,12 @@
-from pypy.objspace.flow.model import traverse, Block, checkgraph
-from pypy.translator.unsimplify import remove_double_links
+import autopath
+from pypy.translator.translator import Translator
+from pypy.objspace.flow.model import Variable, Constant, Block, Link
+from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph
 
 
-def remove_same_as(graph): 
+def remove_same_as(graph):
+    """Remove all 'same_as' operations.
+    """
     same_as_positions = []
     def visit(node): 
         if isinstance(node, Block): 
@@ -33,11 +37,87 @@
         if isinstance(node, Block) and node.operations:
             node.operations[:] = filter(None, node.operations)
     traverse(visit, graph)
-    checkgraph(graph)
 
 
-def prepare_graph(graph, translator):
-    remove_same_as(graph)
-    remove_double_links(translator, graph)
-    return graph
+def SSI_to_SSA(graph):
+    """Rename the variables in a flow graph as much as possible without
+    violating the SSA rule.  'SSI' means that each Variable in a flow graph is
+    defined only once in the whole graph; all our graphs are SSI.  This
+    function does not break that rule, but changes the 'name' of some
+    Variables to give them the same 'name' as other Variables.  The result
+    looks like an SSA graph.  'SSA' means that each var name appears as the
+    result of an operation only once in the whole graph, but it can be
+    passed to other blocks across links.
+    """
+    entrymap = mkentrymap(graph)
+    consider_blocks = entrymap
+
+    while consider_blocks:
+        blocklist = consider_blocks.keys()
+        consider_blocks = {}
+        for block in blocklist:
+            if block is graph.startblock:
+                continue
+            links = entrymap[block]
+            assert links
+            mapping = {}
+            for i in range(len(block.inputargs)):
+                # list of possible vars that can arrive in i'th position
+                v1 = block.inputargs[i]
+                names = {v1.name: True}
+                key = []
+                for link in links:
+                    v = link.args[i]
+                    if not isinstance(v, Variable):
+                        break
+                    names[v.name] = True
+                else:
+                    if len(names) == 2:
+                        del names[v1.name]
+                        v1._name, = names.keys()
+                        # mark all the following block as subject to
+                        # possible further optimization
+                        for link in block.exits:
+                            consider_blocks[link.target] = True
+    # sanity-check that the same name is never used several times in a block
+    variables_by_name = {}
+    for block in entrymap:
+        vars = [op.result for op in block.operations]
+        for link in block.exits:
+            vars += link.getextravars()
+        assert len(dict.fromkeys([v.name for v in vars])) == len(vars), (
+            "duplicate variable name in %r" % (block,))
+        for v in vars:
+            variables_by_name.setdefault(v.name, []).append(v)
+    # sanity-check that variables with the same name have the same concretetype
+    for vname, vlist in variables_by_name.items():
+        vct = [getattr(v, 'concretetype', None) for v in vlist]
+        assert vct == vct[:1] * len(vct), (
+            "variables called %s have mixed concretetypes: %r" % (vname, vct))
+
 
+# ____________________________________________________________
+
+if __name__ == '__main__':
+
+    def is_perfect_number(n=int):
+        div = 1
+        sum = 0
+        while div < n:
+            if n % div == 0:
+                sum += div
+            div += 1
+        return n == sum
+
+    t = Translator(is_perfect_number)
+    a = t.annotate([int])
+    a.simplify()
+    t.specialize()
+    graph = t.getflowgraph()
+    remove_same_as(graph)
+    SSI_to_SSA(graph)
+    checkgraph(graph)
+    t.view()
+    f = t.ccompile()
+    for i in range(1, 33):
+        print '%3d' % i, is_perfect_number(i)



More information about the Pypy-commit mailing list