[pypy-svn] r13605 - in pypy/dist/pypy: tool translator translator/c/test

arigo at codespeak.net arigo at codespeak.net
Sun Jun 19 18:50:14 CEST 2005


Author: arigo
Date: Sun Jun 19 18:50:12 2005
New Revision: 13605

Modified:
   pypy/dist/pypy/tool/unionfind.py
   pypy/dist/pypy/translator/backendoptimization.py
   pypy/dist/pypy/translator/c/test/test_backendoptimized.py
Log:
Sanitized SSI_to_SSA by using the union finder.
I'm more confident that this is doing the right thing now.


Modified: pypy/dist/pypy/tool/unionfind.py
==============================================================================
--- pypy/dist/pypy/tool/unionfind.py	(original)
+++ pypy/dist/pypy/tool/unionfind.py	Sun Jun 19 18:50:12 2005
@@ -4,7 +4,7 @@
 
 class UnionFind(object):
 
-    def __init__(self, info_factory):
+    def __init__(self, info_factory=None):
         self.link_to_parent = {}
         self.weight = {}
         self.info_factory = info_factory
@@ -15,9 +15,9 @@
         if obj not in self.link_to_parent:
             raise KeyError, obj
 
-        ignore, rep, access = self.find(obj)
+        ignore, rep, info = self.find(obj)
 
-        return access
+        return info
 
     def __contains__(self, obj):
         return obj in self.link_to_parent
@@ -31,9 +31,17 @@
     def infos(self):
         return self.root_info.values()
 
+    def find_rep(self, obj):
+        ignore, rep, info = self.find(obj)
+        return rep
+
     def find(self, obj):  # -> new_root, obj, info
         if obj not in self.link_to_parent:
-            info = self.root_info[obj] = self.info_factory(obj)
+            if self.info_factory:
+                info = self.info_factory(obj)
+            else:
+                info = None
+            self.root_info[obj] = info
             self.weight[obj] = 1
             self.link_to_parent[obj] = obj
             return True, obj, info
@@ -66,7 +74,8 @@
         if w1 < w2:
             rep1, rep2, info1, info2, = rep2, rep1, info2, info1
 
-        info1.update(info2)
+        if info1 is not None:
+            info1.update(info2)
 
         self.link_to_parent[rep2] = rep1
 

Modified: pypy/dist/pypy/translator/backendoptimization.py
==============================================================================
--- pypy/dist/pypy/translator/backendoptimization.py	(original)
+++ pypy/dist/pypy/translator/backendoptimization.py	Sun Jun 19 18:50:12 2005
@@ -2,6 +2,7 @@
 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
+from pypy.tool.unionfind import UnionFind
 
 
 def remove_same_as(graph):
@@ -52,8 +53,9 @@
     """
     entrymap = mkentrymap(graph)
     consider_blocks = entrymap
-    renamed = {}
+    variable_families = UnionFind()
 
+    # group variables by families; a family of variables will be identified.
     while consider_blocks:
         blocklist = consider_blocks.keys()
         consider_blocks = {}
@@ -66,30 +68,28 @@
             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}
+                v1 = variable_families.find_rep(v1)
+                inputs = {v1: True}
                 key = []
                 for link in links:
                     v = link.args[i]
                     if not isinstance(v, Variable):
                         break
-                    names[v.name] = True
+                    v = variable_families.find_rep(v)
+                    inputs[v] = True
                 else:
-                    if len(names) == 2:
-                        oldname = v1.name
-                        del names[oldname]
-                        newname, = names.keys()
-                        while oldname in renamed:
-                            oldname = renamed[oldname]
-                        while newname in renamed:
-                            newname = renamed[newname]
-                        if oldname == newname:
-                            continue
-                        renamed[oldname] = newname
-                        v1._name = newname
+                    if len(inputs) == 2:
+                        variable_families.union(*inputs)
                         # mark all the following blocks as subject to
                         # possible further optimization
                         for link in block.exits:
                             consider_blocks[link.target] = True
+    # rename variables to give them the name of their familiy representant
+    for v in variable_families.keys():
+        v1 = variable_families.find_rep(v)
+        if v1 != v:
+            v._name = v1.name
+
     # sanity-check that the same name is never used several times in a block
     variables_by_name = {}
     for block in entrymap:

Modified: pypy/dist/pypy/translator/c/test/test_backendoptimized.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_backendoptimized.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_backendoptimized.py	Sun Jun 19 18:50:12 2005
@@ -25,3 +25,13 @@
             backendoptimization.SSI_to_SSA(graph)
         t.checkgraphs()
         return skip_missing_compiler(t.ccompile)
+
+    def test_remove_same_as(self):
+        def f(n=bool):
+            if bool(bool(bool(n))):
+                return 123
+            else:
+                return 456
+        fn = self.getcompiled(f)
+        assert f(True) == 123
+        assert f(False) == 456



More information about the Pypy-commit mailing list