[pypy-svn] r23333 - in pypy: branch/genc-gc-refactoring dist/pypy/rpython/memory
mwh at codespeak.net
mwh at codespeak.net
Tue Feb 14 15:50:18 CET 2006
Author: mwh
Date: Tue Feb 14 15:50:16 2006
New Revision: 23333
Modified:
pypy/branch/genc-gc-refactoring/funcgen.py
pypy/dist/pypy/rpython/memory/gctransform.py
Log:
attach the same cleanup list (well, tuple now) to multiple operations if
possible.
exploit this to only generate each list of cleanup ops once (so each generated
block of cleanup ops can have >1 label before it).
Modified: pypy/branch/genc-gc-refactoring/funcgen.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/funcgen.py (original)
+++ pypy/branch/genc-gc-refactoring/funcgen.py Tue Feb 14 15:50:16 2006
@@ -299,17 +299,30 @@
raise TypeError("exitswitch type not supported"
" Got %r" % (TYPE,))
+ errorcases = {}
for i, op in list(enumerate(block.operations))[::-1]:
- if hasattr(op, 'cleanup'):
- if not fallthrough:
- yield 'err%d_%d:' % (myblocknum, i)
- else:
- fallthrough = False # this label was already generated
- for cleanupop in op.cleanup:
- for line in self.gen_op(cleanupop, 'should_never_be_jumped_to'):
- yield line
- for line in self.return_with_error():
+ if not hasattr(op, 'cleanup'):
+ continue
+ errorcases.setdefault(op.cleanup, []).append(i)
+
+ if fallthrough:
+ firstclean = tuple(block.operations[-1].cleanup)
+ first = errorcases[firstclean]
+ del errorcases[firstclean]
+ first.remove(len(block.operations) - 1)
+ items = errorcases.items()
+ items.insert(0, (firstclean, first))
+ else:
+ items = errorcases.items()
+
+ for cleanupops, labels in items:
+ for label in labels:
+ yield 'err%d_%d:' % (myblocknum, label)
+ for cleanupop in cleanupops:
+ for line in self.gen_op(cleanupop, 'should_never_be_jumped_to'):
yield line
+ for line in self.return_with_error():
+ yield line
def gen_link(self, link, linklocalvars=None):
"Generate the code to jump across the given Link."
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Tue Feb 14 15:50:16 2006
@@ -99,13 +99,19 @@
def transform_block(self, block):
newops = []
livevars = [var for var in block.inputargs if var_needsgc(var)]
+ livevars2cleanup = {}
for op in block.operations:
newops.extend(self.replacement_operations(op))
# XXX for now we assume that everything can raise
if 1 or op.opname in EXCEPTION_RAISING_OPS:
- cleanup_on_exception = []
- for var in livevars:
- cleanup_on_exception.extend(self.pop_alive(var))
+ if tuple(livevars) in livevars2cleanup:
+ cleanup_on_exception = livevars2cleanup[tuple(livevars)]
+ else:
+ cleanup_on_exception = []
+ for var in livevars:
+ cleanup_on_exception.extend(self.pop_alive(var))
+ cleanup_on_exception = tuple(cleanup_on_exception)
+ livevars2cleanup[tuple(livevars)] = cleanup_on_exception
op.cleanup = cleanup_on_exception
if var_needsgc(op.result):
if op.opname not in ('direct_call', 'indirect_call') and not var_ispyobj(op.result):
More information about the Pypy-commit
mailing list