[pypy-svn] r66536 - pypy/branch/parser-compiler/pypy/interpreter/astcompiler

benjamin at codespeak.net benjamin at codespeak.net
Thu Jul 23 14:58:34 CEST 2009


Author: benjamin
Date: Thu Jul 23 14:58:33 2009
New Revision: 66536

Added:
   pypy/branch/parser-compiler/pypy/interpreter/astcompiler/optimize.py   (contents, props changed)
Modified:
   pypy/branch/parser-compiler/pypy/interpreter/astcompiler/assemble.py
   pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py
Log:
implement simple jump optimizations

Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/assemble.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/assemble.py	(original)
+++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/assemble.py	Thu Jul 23 14:58:33 2009
@@ -214,6 +214,14 @@
                     offset += instr.size()
                     if instr.has_jump:
                         target, absolute = instr.jump
+                        op = instr.opcode
+                        if op == ops.JUMP_ABSOLUTE or op == ops.JUMP_FORWARD:
+                            if target.instructions:
+                                target_op = target.instructions[0].opcode
+                                if target_op == ops.JUMP_ABSOLUTE:
+                                    target = target.instructions[0].jump[0]
+                                    instr.opcode = ops.JUMP_ABSOLUTE
+                                    absolute = True
                         if absolute:
                             jump_arg = target.offset
                         else:

Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py	(original)
+++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py	Thu Jul 23 14:58:33 2009
@@ -4,6 +4,7 @@
 
 from pypy.interpreter.astcompiler import (ast2 as ast, assemble, symtable,
                                           consts, misc)
+from pypy.interpreter.astcompiler import optimize # For side effects
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.tool import stdlib_opcode as ops
 from pypy.interpreter.pyparser import future
@@ -306,8 +307,7 @@
     def visit_Assert(self, asrt):
         self.update_position(asrt.lineno)
         end = self.new_block()
-        asrt.test.walkabout(self)
-        self.emit_jump(ops.JUMP_IF_TRUE, end)
+        asrt.test.accept_jump_if(self, True, end)
         self.emit_op(ops.POP_TOP)
         self.emit_op_name(ops.LOAD_GLOBAL, self.names, "AssertionError")
         if asrt.msg:
@@ -378,8 +378,7 @@
             self.visit_sequence(if_.body)
         else:
             next = self.new_block()
-            if_.test.walkabout(self)
-            self.emit_jump(ops.JUMP_IF_FALSE, next)
+            if_.test.accept_jump_if(self, False, next)
             self.emit_op(ops.POP_TOP)
             self.visit_sequence(if_.body)
             self.emit_jump(ops.JUMP_FORWARD, end)
@@ -462,8 +461,7 @@
             if test_constant == misc.CONST_NOT_CONST:
                 # Force another lineno to be set for tracing purposes.
                 self.lineno_set = False
-                wh.test.walkabout(self)
-                self.emit_jump(ops.JUMP_IF_FALSE, anchor)
+                wh.test.accept_jump_if(self, False, anchor)
                 self.emit_op(ops.POP_TOP)
             self.visit_sequence(wh.body)
             self.emit_jump(ops.JUMP_ABSOLUTE, loop, True)
@@ -777,8 +775,7 @@
         self.update_position(ifexp.lineno)
         end = self.new_block()
         otherwise = self.new_block()
-        ifexp.test.walkabout(self)
-        self.emit_jump(ops.JUMP_IF_FALSE, otherwise)
+        ifexp.test.accept_jump_if(self, False, otherwise)
         self.emit_op(ops.POP_TOP)
         ifexp.body.walkabout(self)
         self.emit_jump(ops.JUMP_FORWARD, end)
@@ -921,8 +918,7 @@
         if gen.ifs:
             if_count = len(gen.ifs)
             for if_ in gen.ifs:
-                if_.walkabout(self)
-                self.emit_jump(ops.JUMP_IF_FALSE, if_cleanup)
+                if_.accept_jump_if(self, False, if_cleanup)
                 self.use_next_block()
                 self.emit_op(ops.POP_TOP)
         else:
@@ -976,8 +972,7 @@
         if gen.ifs:
             ifs_count = len(gen.ifs)
             for if_ in gen.ifs:
-                if_.walkabout(self)
-                self.emit_jump(ops.JUMP_IF_FALSE, if_cleanup)
+                if_.accept_jump_if(self, False, if_cleanup)
                 self.use_next_block()
                 self.emit_op(ops.POP_TOP)
         else:

Added: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/optimize.py
==============================================================================
--- (empty file)
+++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/optimize.py	Thu Jul 23 14:58:33 2009
@@ -0,0 +1,41 @@
+from pypy.interpreter.astcompiler import ast2 as ast
+from pypy.tool import stdlib_opcode as ops
+
+
+class __extend__(ast.expr):
+
+    def accept_jump_if(self, gen, condition, target):
+        self.walkabout(gen)
+        if condition:
+            gen.emit_jump(ops.JUMP_IF_TRUE, target)
+        else:
+            gen.emit_jump(ops.JUMP_IF_FALSE, target)
+
+
+class __extend__(ast.UnaryOp):
+
+    def accept_jump_if(self, gen, condition, target):
+        if self.op == ast.Not:
+            self.operand.accept_jump_if(gen, not condition, target)
+        else:
+            ast.expr.accept_jump_if(self, gen, condition, target)
+
+
+
+class __extend__(ast.BoolOp):
+
+    def _accept_jump_if_any_is(self, gen, condition, target):
+        self.values[0].accept_jump_if(gen, condition, target)
+        for i in range(1, len(self.values)):
+            gen.emit_op(ops.POP_TOP)
+            self.values[i].accept_jump_if(gen, condition, target)
+
+    def accept_jump_if(self, gen, condition, target):
+        if condition and self.op == ast.And or \
+                (not condition and self.op == ast.Or):
+            end = gen.new_block()
+            self._accept_jump_if_any_is(gen, not condition, end)
+            gen.emit_jump(ops.JUMP_FORWARD, target)
+            gen.use_next_block(end)
+        else:
+            self._accept_jump_if_any_is(gen, condition, target)



More information about the Pypy-commit mailing list