[pypy-commit] pypy guard-compatible: simplify optimizer interface to guard-compat. also add more debug prints

cfbolz pypy.commits at gmail.com
Wed Feb 21 12:18:34 EST 2018


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: guard-compatible
Changeset: r93853:4db603258cdc
Date: 2018-02-20 12:13 +0100
http://bitbucket.org/pypy/pypy/changeset/4db603258cdc/

Log:	simplify optimizer interface to guard-compat. also add more debug
	prints

diff --git a/rpython/jit/metainterp/compatible.py b/rpython/jit/metainterp/compatible.py
--- a/rpython/jit/metainterp/compatible.py
+++ b/rpython/jit/metainterp/compatible.py
@@ -83,8 +83,12 @@
             cond.activate_secondary(ref, loop_token)
         return True
 
-    def prepare_const_arg_call(self, op, optimizer):
-        copied_op, cond = self._prepare_const_arg_call(op, optimizer)
+    def replace_with_const_result_if_possible(self, op, optimizer):
+        """ Main entry point for optimizeopt: check if op can be replaced with
+        a constant result and stored in the conditions instead of leaving it in
+        the trace. Returns None if that is not possible. """
+        copied_op, cond, failure_reason = self._prepare_const_arg_call(
+                op, optimizer)
         if copied_op:
             result = optimizer._can_optimize_call_pure(copied_op)
             if result is None:
@@ -93,9 +97,23 @@
                 result = do_call(
                         optimizer.cpu, copied_op.getarglist(),
                         copied_op.getdescr())
-            return copied_op, cond, result
-        else:
-            return None, None, None
+            recorded = self.record_condition(
+                    cond, result, optimizer)
+            if recorded:
+                return result
+            else:
+                failure_reason = "self is frozen"
+        debug_start("jit-guard-compatible")
+        if have_debug_prints():
+            try:
+                addr = op.getarg(0).getaddr()
+            except Exception:
+                funcname = "?"
+            else:
+                funcname = optimizer.metainterp_sd.get_name_from_address(addr)
+            debug_print("failed to optimize call:", funcname, failure_reason)
+            debug_stop("jit-guard-compatible")
+        return None
 
     def _prepare_const_arg_call(self, op, optimizer):
         from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
@@ -112,15 +130,16 @@
         copied_op = op.copy()
         copied_op.setarg(1, self.known_valid)
         if op.numargs() == 2:
-            return copied_op, PureCallCondition(op, optimizer)
+            return copied_op, PureCallCondition(op, optimizer), ""
         arg2 = copied_op.getarg(2)
         if arg2.is_constant():
             # already a constant, can just use PureCallCondition
             if last_nonconst_index != -1:
-                return None, None # a non-constant argument, can't optimize
-            return copied_op, PureCallCondition(op, optimizer)
+                # a non-constant argument, can't optimize
+                return None, None, "nonconstant arg " + str(last_nonconst_index)
+            return copied_op, PureCallCondition(op, optimizer), ""
         if last_nonconst_index != 2:
-            return None, None
+            return None, None, "nonconstant arg " + str(last_nonconst_index)
 
         # really simple-minded pattern matching
         # the order of things is like this:
@@ -132,20 +151,20 @@
         # make it possible for the GUARD_COMPATIBLE to still remove the call,
         # even though the second argument is not constant
         if arg2.getopnum() not in (rop.GETFIELD_GC_R, rop.GETFIELD_GC_I, rop.GETFIELD_GC_F):
-            return None, None
+            return None, None, "arg2 not a getfield"
         if not self.last_quasi_immut_field_op:
-            return None, None
+            return None, None, "no quasiimut op known"
         qmutdescr = self.last_quasi_immut_field_op.getdescr()
         assert isinstance(qmutdescr, QuasiImmutDescr)
         fielddescr = qmutdescr.fielddescr # XXX
         same_arg = self.last_quasi_immut_field_op.getarg(0) is arg2.getarg(0)
         if arg2.getdescr() is not fielddescr or not same_arg:
-            return None, None
+            return None, None, "fielddescr doesn't match"
         if not qmutdescr.is_still_valid_for(self.known_valid):
-            return None, None
+            return None, None, "qmutdescr invalid"
         copied_op.setarg(2, qmutdescr.constantfieldbox)
         return copied_op, QuasiimmutGetfieldAndPureCallCondition(
-                op, qmutdescr, optimizer)
+                op, qmutdescr, optimizer), ""
 
     def emit_conditions(self, op, short, optimizer):
         """ re-emit the conditions about variable op into the short preamble
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -166,15 +166,12 @@
                     ccond = info._compatibility_conditions
                     if ccond:
                         # it's subject to guard_compatible
-                        copied_op, cond, result = ccond.prepare_const_arg_call(
-                                op, self.optimizer)
-                        if copied_op:
-                            recorded = ccond.record_condition(
-                                    cond, result, self.optimizer)
-                            if recorded:
-                                self.make_constant(op, result)
-                                self.last_emitted_operation = REMOVED
-                                return
+                        result = ccond.replace_with_const_result_if_possible(
+                            op, self.optimizer)
+                        if result:
+                            self.make_constant(op, result)
+                            self.last_emitted_operation = REMOVED
+                            return
 
         # Step 1: check if all arguments are constant
         for i in range(start_index, op.numargs()):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -531,7 +531,7 @@
         op = ResOperation(
                 rop.CALL_PURE_I, [ConstInt(123), ConstPtr(self.quasiptr)],
                 descr=self.plaincalldescr)
-        copied_op, cond, result = ccond.prepare_const_arg_call(
+        copied_op, cond, reason = ccond._prepare_const_arg_call(
                 op, optimizer)
         ccond.record_condition(cond, ConstInt(5), optimizer)
 
@@ -545,7 +545,7 @@
                 rop.CALL_PURE_I,
                 [ConstInt(123), ConstPtr(self.quasiptr), getfield_op],
                 descr=self.nonwritedescr)
-        copied_op, cond, result = ccond.prepare_const_arg_call(
+        copied_op, cond, reason = ccond._prepare_const_arg_call(
                 op, optimizer)
         ccond.record_condition(cond, ConstInt(5), optimizer)
         value = info.PtrInfo()


More information about the pypy-commit mailing list