[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