[pypy-commit] pypy slightly-shorter-c: Rework the generated assembler to avoid duplicating operations

arigo noreply at buildbot.pypy.org
Fri Jun 8 18:58:20 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: slightly-shorter-c
Changeset: r55520:aff548961c1e
Date: 2012-06-08 18:57 +0200
http://bitbucket.org/pypy/pypy/changeset/aff548961c1e/

Log:	Rework the generated assembler to avoid duplicating operations in
	the blocks that are the heads of loops.

diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py
--- a/pypy/translator/c/funcgen.py
+++ b/pypy/translator/c/funcgen.py
@@ -214,6 +214,10 @@
             myblocknum = self.blocknum[block]
             yield ''
             yield 'block%d:' % myblocknum
+            if block in self.innerloops:
+                for line in self.gen_while_loop_hack(block):
+                    yield line
+                continue
             for i, op in enumerate(block.operations):
                 for line in self.gen_op(op):
                     yield line
@@ -236,9 +240,6 @@
                 assert len(block.exits) == 1
                 for op in self.gen_link(block.exits[0]):
                     yield op
-            elif block in self.innerloops:
-                for line in self.gen_while_loop_hack(block):
-                    yield line
             else:
                 assert block.exitswitch != c_last_exception
                 # block ending in a switch on a value
@@ -341,11 +342,11 @@
         # decision is) we produce code like this:
         #
         #             headblock:
-        #               ...headblock operations...
-        #               while (cond) {
+        #               while (1) {
+        #                   ...headblock operations...
+        #                   if (!cond) break;
         #                   goto firstbodyblock;
-        #                 headblock_back:
-        #                   ...headblock operations...
+        #                 headblock_back: ;
         #               }
         #
         # The real body of the loop is not syntactically within the
@@ -366,19 +367,19 @@
         i = list(headblock.exits).index(enterlink)
         exitlink = headblock.exits[1 - i]
 
+        yield 'while (1) {'
+
+        for i, op in enumerate(headblock.operations):
+            for line in self.gen_op(op):
+                yield '\t' + line
+
         expr = self.expr(headblock.exitswitch)
-        if enterlink.exitcase == False:
+        if enterlink.exitcase == True:
             expr = '!' + expr
-        yield 'while (%s) {' % expr
+        yield '\tif (%s) break;' % expr
         for op in self.gen_link(enterlink):
             yield '\t' + op
-        # the semicolon after the colon is needed in case no operation
-        # produces any code after the label
-        yield '\t  block%d_back: ;' % self.blocknum[headblock]
-        if headblock.operations:
-            for i, op in enumerate(headblock.operations):
-                for line in self.gen_op(op):
-                    yield '\t' + line
+        yield '  block%d_back: ;' % self.blocknum[headblock]
         yield '}'
         for op in self.gen_link(exitlink):
             yield op


More information about the pypy-commit mailing list