[pypy-commit] pypy interp-opt: start to think about some light weight specialization optimization done purely in the interpreter (working on a test)
plan_rich
pypy.commits at gmail.com
Wed Oct 19 12:58:45 EDT 2016
Author: Richard Plangger <planrichi at 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:
More information about the pypy-commit
mailing list