[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