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