[pypy-svn] r48353 - in pypy/dist/pypy/translator/backendopt: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Nov 7 12:32:50 CET 2007


Author: cfbolz
Date: Wed Nov  7 12:32:48 2007
New Revision: 48353

Modified:
   pypy/dist/pypy/translator/backendopt/coalloc.py
   pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
Log:
more exact heuristics


Modified: pypy/dist/pypy/translator/backendopt/coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/coalloc.py	(original)
+++ pypy/dist/pypy/translator/backendopt/coalloc.py	Wed Nov  7 12:32:48 2007
@@ -347,19 +347,48 @@
 
 def do_coalloc(adi, graph, setblock, setop, fromcreps, tocrep):
     def find_coalloc_var():
+        # if the setting happens in the same block as the malloc, use the
+        # variable directly
         if block is setblock and seen_setvar:
             return setop.args[0]
-        for fromcrep in fromcreps:
+
+        # if the setting _always_ happens on a constant, use the constant
+        if len(fromcreps) == 1:
+            fromcrep, = fromcreps
             if fromcrep.creation_method == "constant":
                 return fromcrep.constant
+
+        # lots of heuristics ahead
+        subsets = []
+        intersections = []
+        for var in block.inputargs:
+            varstate = adi.getstate(var)
+            if varstate is None:
+                continue
+            creps = set(varstate.creation_points)
+            if creps == fromcreps:
+                return var
+            if creps.issubset(fromcreps):
+                subsets.append((len(creps), var))
+            intersection = creps.intersection(fromcreps)
+            if intersection:
+                intersections.append((len(intersection), var))
+
+        # first, try to use the biggest subset of creps
+        if subsets:
+            subsets.sort()
+            return subsets[-1][1]
+        # then, get desparate, and use any inputarg that has the biggest
+        # intersection
+        if intersections:
+            intersections.sort()
+            return intersections[-1][1]
+
+        # if there is still nothing, check the fromcreps again and look for
+        # a constant
         for fromcrep in fromcreps:
-            for var in block.inputargs:
-                varstate = adi.getstate(var)
-                if varstate is None:
-                    continue
-                crep = varstate.get_crep(checksingle=True)
-                if crep is fromcrep:
-                    return var
+            if fromcrep.creation_method == "constant":
+                return fromcrep.constant
         return None
     result = 0
     for block in graph.iterblocks():

Modified: pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_coalloc.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_coalloc.py	Wed Nov  7 12:32:48 2007
@@ -299,3 +299,29 @@
         a.next = n
         return 1
     check_malloc_to_coalloc(f, [], [], 1, must_remove=0)
+
+def test_coalloc_set_further_down():
+    class A(object):
+        pass
+    def g():
+        return A()
+    globala = A()
+    globala.x = 2
+    def f(x):
+        if x:
+            a = g()
+            a.x = 42
+        else:
+            a = g()
+            a.x = 43
+        a1 = A()
+        a.x = 1
+        # this if is only there to force the set into a new block
+        if not x:
+            b = a
+        else:
+            b = globala
+        a.a = a1
+        return b.x
+    t = check_malloc_to_coalloc(f, [int], [1], 2, must_remove=1)
+



More information about the Pypy-commit mailing list