Author: Richard Plangger <planri...@gmail.com> Branch: interp-opt Changeset: r87883:84d5cd4effa1 Date: 2016-10-19 18:57 +0200 http://bitbucket.org/pypy/pypy/changeset/84d5cd4effa1/
Log: start to think about some light weight specialization optimization done purely in the interpreter (working on a test) diff --git a/pypy/interpreter/optimizer/__init__.py b/pypy/interpreter/optimizer/__init__.py new file mode 100644 --- /dev/null +++ b/pypy/interpreter/optimizer/__init__.py @@ -0,0 +1,5 @@ + + +def optimize(instrs, obval): + return opcode + diff --git a/pypy/interpreter/optimizer/rules.py b/pypy/interpreter/optimizer/rules.py new file mode 100644 --- /dev/null +++ b/pypy/interpreter/optimizer/rules.py @@ -0,0 +1,12 @@ + +from pypy.interperter.pyopcode import opcodedesc as bc + + +OPT_RULES = {} + +def binary_rule(opcode, types, enhanced_code): + global OPT_RULES + OPT_RULES[opcode] = (types, enhanced_code) + +binary_rule(bc.BINARY_ADD, [Types.FLOAT, Types.FLOAT], bc.BINARY_ADD_FLOAT_FLOAT) + diff --git a/pypy/interpreter/optimizer/test/test_basic_func_opt.py b/pypy/interpreter/optimizer/test/test_basic_func_opt.py new file mode 100644 --- /dev/null +++ b/pypy/interpreter/optimizer/test/test_basic_func_opt.py @@ -0,0 +1,68 @@ +import py +from pypy.interpreter import gateway, module, error +from pypy.interpreter.optimizer import optimize + +class TestBytecode(object): + def __init__(self, pycode): + self.pycode = pycode + + def has(self, opcode): + return True # XXX + +class TestVersioning: + def codetest(self, source, functionname, args): + """Compile and run the given code string, and then call its function + named by 'functionname' with arguments 'args'.""" + space = self.space + + source = str(py.code.Source(source).strip()) + '\n' + + w = space.wrap + w_code = space.builtin.call('compile', + w(source), w('<string>'), w('exec'), w(0), w(0)) + + tempmodule = module.Module(space, w("__temp__")) + w_glob = tempmodule.w_dict + space.setitem(w_glob, w("__builtins__"), space.builtin) + + code = space.unwrap(w_code) + code.exec_code(space, w_glob, w_glob) + + w_args = [w(a) for a in args] + w_func = space.getitem(w_glob, w(functionname)) + fcode = space.unwrap(space.getattr(w_func, w('__code__'))) + fcode.start_type_recording() + try: + w_a = space.call_function(w_func, *w_args) + except error.OperationError as e: + #e.print_detailed_traceback(space) + return '<<<%s>>>' % e.errorstr(space) + + opt_fcode = optimize(fcode) + space.setitem(w_func, w('__code__'), opt_fcode) + try: + w_b = space.call_function(w_func, *w_args) + except error.OperationError as e: + #e.print_detailed_traceback(space) + return '<<<%s>>>' % e.errorstr(space) + a = space.unwrap(w_a) + b = space.unwrap(w_b) + return a, TestBytecode(fcode), b, TestBytecode(opt_fcode) + + def test_record_types(self): + code = self.coderecord(""" + def f(v): + return v + 1.0 + """, 'f', [1.0]) + assert self.recorded(code, [ + (0, 1, 'FLOAT') + ]) + + def test_specialize_float(self): + code = """ + def f(v): + return v + 1.0 + """ + a, acode, b, bcode = self.codetest(code, 'f', [1.0]) + assert a == 2.0 == b + assert not bcode.has(BINARY_ADD) diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -96,6 +96,10 @@ self._initialize() self._init_ready() self.new_code_hook() + self.record = None + + def start_type_recording(self): + self.record = [] def frame_stores_global(self, w_globals): if self.w_globals is None: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit