[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