[pypy-svn] r22746 - in pypy/dist/pypy/rpython/memory: . test
mwh at codespeak.net
mwh at codespeak.net
Fri Jan 27 17:38:52 CET 2006
Author: mwh
Date: Fri Jan 27 17:38:50 2006
New Revision: 22746
Modified:
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
(cfbolz,mwh)
Fix logic for what to do with variables passed across links in the case that
more than one variable is passed.
Add a general consistency check that would have caught this and apply it to
every block of every graph that gets transformed.
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Fri Jan 27 17:38:50 2006
@@ -37,11 +37,18 @@
self.links_to_split = {} # link -> vars to pop_alive across the link
for block in graph.iterblocks():
self.transform_block(block)
- for link, vars in self.links_to_split.iteritems():
+ for link, livecounts in self.links_to_split.iteritems():
newops = []
- for var in vars:
- newops.extend(self.pop_alive(var))
- insert_empty_block(None, link, newops)
+ for var, livecount in livecounts.iteritems():
+ for i in range(livecount):
+ newops.extend(self.pop_alive(var))
+ for i in range(-livecount):
+ newops.extend(self.push_alive(var))
+ if newops:
+ if len(link.prevblock.exits) == 1:
+ link.prevblock.operations.extend(newops)
+ else:
+ insert_empty_block(None, link, newops)
def transform_block(self, block):
newops = []
@@ -60,10 +67,6 @@
if len(block.exits) == 0:
# everything is fine already for returnblocks and exceptblocks
pass
- elif len(block.exits) == 1:
- for var in livevars:
- if var not in block.exits[0].args:
- newops.extend(self.pop_alive(var))
else:
deadinallexits = sets.Set(livevars)
for link in block.exits:
@@ -71,9 +74,11 @@
for var in deadinallexits:
newops.extend(self.pop_alive(var))
for link in block.exits:
- deadvarsforlink = sets.Set(livevars) - deadinallexits - sets.Set(link.args)
- if deadvarsforlink:
- self.links_to_split[link] = deadvarsforlink
+ livecounts = dict.fromkeys(sets.Set(livevars) - deadinallexits, 1)
+ for v in link.args:
+ if v in livecounts:
+ livecounts[v] -= 1
+ self.links_to_split[link] = livecounts
if newops:
block.operations = newops
Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py Fri Jan 27 17:38:50 2006
@@ -1,6 +1,25 @@
from pypy.rpython.memory import gctransform
+from pypy.rpython.memory.gctransform import var_needsgc
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.lltypesystem import lltype
+from pypy.objspace.flow.model import Variable
+
+def checkblock(block):
+ vars_in = len([v for v in block.inputargs if var_needsgc(v)])
+ push_alives = len([op for op in block.operations
+ if op.opname.startswith('gc_push_alive')])
+ pop_alives = len([op for op in block.operations
+ if op.opname.startswith('gc_pop_alive')])
+ calls = len([op for op in block.operations
+ if 'direct_call' in op.opname and var_needsgc(op.result)])
+ if pop_alives == len(block.operations):
+ # it's a block we inserted
+ return
+ for link in block.exits:
+ vars_out = len([v for v in link.args
+ if isinstance(v, Variable) and var_needsgc(v)])
+ assert vars_in + push_alives + calls == pop_alives + vars_out
+
def rtype_and_transform(func, inputtypes, transformcls):
t = TranslationContext()
@@ -9,6 +28,9 @@
transformer = transformcls(t.graphs)
transformer.transform()
t.checkgraphs()
+ for graph in t.graphs:
+ for block in graph.iterblocks():
+ checkblock(block)
return t
def test_simple():
@@ -105,6 +127,21 @@
assert direct_calls[1].args[1].value[0].args[0] == direct_calls[0].result
assert [op.args[0] for op in direct_calls[2].args[1].value] == [direct_calls[0].result, direct_calls[1].result]
+def test_multiply_passed_var():
+ S = lltype.GcStruct("S", ('x', lltype.Signed))
+ def f(x):
+ if x:
+ a = lltype.malloc(S)
+ a.x = 1
+ b = a
+ else:
+ a = lltype.malloc(S)
+ a.x = 1
+ b = lltype.malloc(S)
+ b.x = 2
+ return a.x + b.x
+ t = rtype_and_transform(f, [int], gctransform.GCTransformer)
+
def test_pyobj():
def f(x):
if x:
More information about the Pypy-commit
mailing list