[pypy-svn] pypy default: A peepoler optimization: a JUMP to RETURN becomes a RETURN.
amauryfa
commits-noreply at bitbucket.org
Wed Jan 19 20:33:35 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r40953:8332e72b048f
Date: 2011-01-19 20:32 +0100
http://bitbucket.org/pypy/pypy/changeset/8332e72b048f/
Log: A peepoler optimization: a JUMP to RETURN becomes a RETURN.
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1,9 +1,10 @@
import py
-from pypy.interpreter.astcompiler import codegen, astbuilder
+from pypy.interpreter.astcompiler import codegen, astbuilder, symtable
from pypy.interpreter.pyparser import pyparse
from pypy.interpreter.pyparser.test import expressions
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pyparser.error import SyntaxError, IndentationError
+from pypy.tool import stdlib_opcode as ops
def compile_with_astcompiler(expr, mode, space):
p = pyparse.PythonParser(space)
@@ -12,6 +13,18 @@
ast = astbuilder.ast_from_node(space, cst, info)
return codegen.compile_ast(space, ast, info)
+def generate_function_code(expr, space):
+ p = pyparse.PythonParser(space)
+ info = pyparse.CompileInfo("<test>", 'exec')
+ cst = p.parse_source(expr, info)
+ ast = astbuilder.ast_from_node(space, cst, info)
+ function_ast = ast.body[0]
+ symbols = symtable.SymtableBuilder(space, ast, info)
+ generator = codegen.FunctionCodeGenerator(
+ space, 'function', function_ast, 1, symbols, info)
+ blocks = generator.first_block.post_order()
+ generator._resolve_block_targets(blocks)
+ return generator, blocks
class TestCompiler:
"""These tests compile snippets of code and check them by
@@ -771,3 +784,21 @@
print >> s, "hi", "lovely!",
assert s.getvalue() == "hi lovely!"
""" in {}
+
+class TestOptimizations:
+
+ def test_elim_jump_to_return(self):
+ source = """def f():
+ return true_value if cond else false_value
+ """
+ code, blocks = generate_function_code(source, self.space)
+ instrs = []
+ for block in blocks:
+ instrs.extend(block.instructions)
+ print instrs
+ counts = {}
+ for instr in instrs:
+ counts[instr.opcode] = counts.get(instr.opcode, 0) + 1
+ assert ops.JUMP_FORWARD not in counts
+ assert ops.JUMP_ABSOLUTE not in counts
+ assert counts[ops.RETURN_VALUE] == 2
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -286,6 +286,12 @@
target = target.instructions[0].jump[0]
instr.opcode = ops.JUMP_ABSOLUTE
absolute = True
+ elif target_op == ops.RETURN_VALUE:
+ # Replace JUMP_* to a RETURN into just a RETURN
+ instr.opcode = ops.RETURN_VALUE
+ instr.arg = 0
+ instr.has_jump = False
+ continue
if absolute:
jump_arg = target.offset
else:
More information about the Pypy-commit
mailing list