Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: guard-compatible
Changeset: r83196:07d318a03f0d
Date: 2016-03-20 15:20 +0100
http://bitbucket.org/pypy/pypy/changeset/07d318a03f0d/

Log:    de-duplicate quasi-immutable conditions

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
@@ -157,6 +157,8 @@
             return False
         if not self.res.same_constant(res):
             return False
+        if self.descr is not other.descr:
+            return False
         assert self.args[1] is other.args[1] is None
         for i in range(len(self.args)):
             if i == 1:
@@ -168,28 +170,36 @@
 
 class QuasiimmutGetfieldAndPureCallCondition(PureCallCondition):
     def __init__(self, op, qmutdescr):
-        self.op = op
-        self.qmutdescr = qmutdescr
+        args = op.getarglist()[:]
+        args[1] = None
+        args[2] = None
+        self.args = args
+        self.descr = op.getdescr()
+        self.qmut = qmutdescr.qmut
+        self.mutatefielddescr = qmutdescr.mutatefielddescr
+        self.fielddescr = qmutdescr.fielddescr
 
     def activate(self, ref, optimizer):
         # record the quasi-immutable
-        optimizer.record_quasi_immutable_dep(self.qmutdescr.qmut)
+        optimizer.record_quasi_immutable_dep(self.qmut)
+        # XXX can set self.qmut to None here?
         Condition.activate(self, ref, optimizer)
 
     def activate_secondary(self, ref, loop_token):
         from rpython.jit.metainterp.quasiimmut import get_current_qmut_instance
         # need to register the loop for invalidation as well!
         qmut = get_current_qmut_instance(loop_token.cpu, ref,
-                                         self.qmutdescr.mutatefielddescr)
+                                         self.mutatefielddescr)
         qmut.register_loop_token(loop_token.loop_token_wref)
 
     def check(self, cpu, ref):
         from rpython.rlib.debug import debug_print, debug_start, debug_stop
-        calldescr = self.op.getdescr()
+        from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
+        calldescr = self.descr
         # change exactly the first argument
-        arglist = self.op.getarglist()
+        arglist = self.args
         arglist[1] = newconst(ref)
-        arglist[2] = self.qmutdescr._get_fieldvalue(ref)
+        arglist[2] = QuasiImmutDescr._get_fieldvalue(self.fielddescr, ref, cpu)
         try:
             res = do_call(cpu, arglist, calldescr)
         except Exception:
@@ -197,7 +207,30 @@
             debug_print("call to elidable_compatible function raised")
             debug_stop("jit-guard-compatible")
             return False
+        finally:
+            arglist[1] = arglist[2] = None
         if not res.same_constant(self.res):
             return False
         return True
 
+    def same_cond(self, other, res):
+        if type(other) != QuasiimmutGetfieldAndPureCallCondition:
+            return False
+        if len(self.args) != len(other.args):
+            return False
+        if not self.res.same_constant(res):
+            return False
+        if self.descr is not other.descr:
+            return False
+        if self.fielddescr is not other.fielddescr:
+            return False
+        if self.mutatefielddescr is not other.mutatefielddescr:
+            return False
+        assert self.args[1] is other.args[1] is None
+        assert self.args[2] is other.args[2] is None
+        for i in range(len(self.args)):
+            if i == 1 or i == 2:
+                continue
+            if not self.args[i].same_constant(other.args[i]):
+                return False
+        return True
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_compatible.py 
b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
@@ -150,7 +150,12 @@
         guard_not_invalidated() []
         i0 = getfield_gc_i(p1, descr=quasifielddescr)
         i1 = call_pure_i(123, p1, i0, descr=nonwritedescr)
+        quasiimmut_field(p1, descr=quasiimmutdescr)
+        guard_not_invalidated() []
+        i3 = getfield_gc_i(p1, descr=quasifielddescr)
+        i4 = call_pure_i(123, p1, i3, descr=nonwritedescr)
         escape_n(i1)
+        escape_n(i4)
         jump(p1)
         """
         expected = """
@@ -159,10 +164,14 @@
         guard_not_invalidated() []
         i0 = getfield_gc_i(p1, descr=quasifielddescr) # will be removed by the 
backend
         escape_n(5)
+        escape_n(5)
         jump(p1)
         """
         call_pure_results = {
             (ConstInt(123), ConstPtr(self.quasiptr), ConstInt(-4247)): 
ConstInt(5),
         }
         self.optimize_loop(ops, expected, call_pure_results)
-
+        descr = self.loop.operations[1].getdescr()
+        assert descr._compatibility_conditions is not None
+        assert 
descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.quasiptr))
+        assert len(descr._compatibility_conditions.conditions) == 1
diff --git a/rpython/jit/metainterp/quasiimmut.py 
b/rpython/jit/metainterp/quasiimmut.py
--- a/rpython/jit/metainterp/quasiimmut.py
+++ b/rpython/jit/metainterp/quasiimmut.py
@@ -129,16 +129,16 @@
 
     def get_current_constant_fieldvalue(self):
         struct = self.struct
-        return self._get_fieldvalue(struct)
+        return self._get_fieldvalue(self.fielddescr, struct, self.cpu)
 
-    def _get_fieldvalue(self, struct):
-        fielddescr = self.fielddescr
-        if self.fielddescr.is_pointer_field():
-            return ConstPtr(self.cpu.bh_getfield_gc_r(struct, fielddescr))
-        elif self.fielddescr.is_float_field():
-            return ConstFloat(self.cpu.bh_getfield_gc_f(struct, fielddescr))
+    @staticmethod
+    def _get_fieldvalue(fielddescr, struct, cpu):
+        if fielddescr.is_pointer_field():
+            return ConstPtr(cpu.bh_getfield_gc_r(struct, fielddescr))
+        elif fielddescr.is_float_field():
+            return ConstFloat(cpu.bh_getfield_gc_f(struct, fielddescr))
         else:
-            return ConstInt(self.cpu.bh_getfield_gc_i(struct, fielddescr))
+            return ConstInt(cpu.bh_getfield_gc_i(struct, fielddescr))
 
     def is_still_valid_for(self, structconst):
         assert self.struct
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to