[pypy-svn] r48269 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Nov 3 16:19:46 CET 2007
Author: cfbolz
Date: Sat Nov 3 16:19:46 2007
New Revision: 48269
Modified:
pypy/dist/pypy/translator/backendopt/coalloc.py
pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
Log:
replace mallocs by coallocs
Modified: pypy/dist/pypy/translator/backendopt/coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/coalloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/coalloc.py Sat Nov 3 16:19:46 2007
@@ -7,6 +7,7 @@
from pypy.tool.uid import uid
class CreationPoint(object):
+ constant = None
def __init__(self, creation_method, TYPE):
self.creation_method = creation_method
self.TYPE = TYPE
@@ -64,6 +65,7 @@
else:
if var_or_const not in self.constant_cps:
crep = CreationPoint("constant", var_or_const.concretetype)
+ crep.constant = var_or_const
self.constant_cps[var_or_const] = crep
else:
crep = self.constant_cps[var_or_const]
@@ -154,8 +156,7 @@
return
if isonheap(op.result) or filter(None, args):
- raise NotImplementedError("can't handle %s" % (op.opname, ))
- #print "assuming that '%s' is irrelevant" % op
+ print "assuming that '%s' is irrelevant" % op
def complete(self):
while self.scheduled:
@@ -304,4 +305,59 @@
if graph.startblock not in adi.flown_blocks:
adi.schedule_function(graph)
adi.complete()
- return adi
+ look_at = t.graphs[:]
+ total = 0
+ while look_at:
+ graph = look_at.pop()
+ for block, op in graph.iterblockops():
+ if not op.opname.startswith("set"):
+ continue
+ if not isonheap(op.args[-1]):
+ continue
+ tovarstate = adi.getstate(op.args[-1])
+ fromvarstate = adi.getstate(op.args[0])
+ if (len(tovarstate.creation_points) != 1 or
+ len(fromvarstate.creation_points) != 1):
+ continue
+ fromcrep = fromvarstate.creation_points.keys()[0]
+ tocrep = tovarstate.creation_points.keys()[0]
+ if not tocrep.creation_method.startswith("malloc"):
+ continue
+ if fromcrep.creation_method.startswith("malloc"):
+ continue # also recently malloced
+
+ num = do_coalloc(adi, graph, fromcrep, tocrep)
+
+ if num:
+ look_at.append(graph)
+ print "changed %s mallocs to coallocs in %s" % (num, graph.name)
+ total += num
+ return total
+
+
+def do_coalloc(adi, graph, fromcrep, tocrep):
+ result = 0
+ for block, op in graph.iterblockops():
+ if not op.opname.startswith("malloc"):
+ continue
+ # find coallocation var
+ if fromcrep.creation_method == "constant":
+ coallocvar = fromcrep.constant
+ else:
+ for var in block.inputargs:
+ varstate = adi.getstate(var)
+ assert len(varstate.creation_points) == 1
+ crep = varstate.creation_points.keys()[0]
+ if crep is fromcrep:
+ coallocvar = var
+ break
+ else:
+ continue
+ op.opname = "coalloc" + op.opname[len("malloc"):]
+ op.args.insert(1, coallocvar)
+ mallocvarstate = adi.getstate(op.result)
+ assert len(mallocvarstate.creation_points) == 1
+ malloccrep = mallocvarstate.creation_points.keys()[0]
+ malloccrep.creation_method = "coalloc"
+ result += 1
+ return result
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 Sat Nov 3 16:19:46 2007
@@ -1,5 +1,5 @@
from pypy.translator.translator import TranslationContext, graphof
-from pypy.translator.backendopt.coalloc import AbstractDataFlowInterpreter
+from pypy.translator.backendopt.coalloc import AbstractDataFlowInterpreter, malloc_to_coalloc
from pypy.rpython.llinterp import LLInterpreter
from pypy.rlib.objectmodel import instantiate
from pypy import conftest
@@ -18,6 +18,27 @@
adi.complete()
return t, adi, graph
+def check_malloc_to_coalloc(function, types, args, expected_result, must_remove=-1):
+ t = TranslationContext()
+ t.buildannotator().build_types(function, types)
+ t.buildrtyper().specialize()
+ interp = LLInterpreter(t.rtyper)
+ graph = graphof(t, function)
+ res = interp.eval_graph(graph, args)
+ assert res == expected_result
+ num = malloc_to_coalloc(t)
+ if must_remove == -1:
+ for block in graph.iterblocks():
+ for op in block.operations:
+ assert op.opname != "malloc"
+ else:
+ assert num == must_remove
+ t.view()
+ res = interp.eval_graph(graph, args)
+ assert res == expected_result
+ return t
+
+
def test_simple():
class A(object):
pass
@@ -112,3 +133,41 @@
for crep in state.creation_points.keys():
assert crep.creation_method == "malloc"
+def test_coalloc_constants():
+ class A(object):
+ pass
+ a = A()
+ def f():
+ n = A()
+ a.next = n
+ return 1
+ check_malloc_to_coalloc(f, [], [], 1)
+
+def test_nocoalloc_aliasing():
+ class A:
+ pass
+ def fn6(n):
+ a1 = A()
+ a1.x = 5
+ a2 = A()
+ a2.x = 6
+ if n > 0:
+ a = a1
+ else:
+ a = a2
+ a.x = 12
+ return a1.x
+ t = check_malloc_to_coalloc(fn6, [int], [2], 12, must_remove=0)
+
+def test_coalloc_with_arg():
+ class A(object):
+ pass
+ def g(b):
+ b.x = A()
+ def f():
+ a = A()
+ g(a)
+ a.i = 2
+ return 4
+ t = check_malloc_to_coalloc(f, [], [], 4, must_remove=1)
+
More information about the pypy-svn
mailing list