Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: guard-compatible Changeset: r85162:349d440cf935 Date: 2016-06-14 17:52 +0200 http://bitbucket.org/pypy/pypy/changeset/349d440cf935/
Log: fix a bug in the guard_compatible handling in optimizeopt. (if the arguments to the call_pure were non-constants that the optimizer would discover to be constants, things would break) 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 @@ -56,6 +56,13 @@ def prepare_const_arg_call(self, op, optimizer): from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr + # replace further arguments by constants, if the optimizer knows them + # already + for i in range(2, op.numargs()): + arg = op.getarg(i) + constarg = optimizer.get_constant_box(arg) + if constarg is not None: + op.setarg(i, constarg) copied_op = op.copy() copied_op.setarg(1, self.known_valid) if op.numargs() == 2: @@ -147,11 +154,17 @@ return "<huh?>" class PureCallCondition(Condition): + const_args_start_at = 2 + def __init__(self, op, optimizer): + from rpython.jit.metainterp.history import Const Condition.__init__(self, optimizer) args = op.getarglist()[:] args[1] = None self.args = args + for index in range(self.const_args_start_at, len(args)): + arg = args[index] + assert isinstance(arg, Const) self.descr = op.getdescr() self.rpyfunc = op.rpyfunc @@ -210,14 +223,11 @@ class QuasiimmutGetfieldAndPureCallCondition(PureCallCondition): + const_args_start_at = 3 + def __init__(self, op, qmutdescr, optimizer): - Condition.__init__(self, optimizer) - args = op.getarglist()[:] - args[1] = None - args[2] = None - self.args = args - self.descr = op.getdescr() - self.rpyfunc = op.rpyfunc + PureCallCondition.__init__(self, op, optimizer) + self.args[2] = None self.qmut = qmutdescr.qmut self.mutatefielddescr = qmutdescr.mutatefielddescr self.fielddescr = qmutdescr.fielddescr 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 @@ -35,14 +35,14 @@ def test_guard_compatible_and_guard_nonnull(self): ops = """ [p1] - guard_nonnull(p1, ConstClass(node_vtable)) [] + guard_nonnull(p1) [] guard_compatible(p1, ConstPtr(myptr)) [] - guard_nonnull(p1, ConstClass(node_vtable)) [] + guard_nonnull(p1) [] jump(ConstPtr(myptr)) """ expected = """ [p1] - guard_nonnull(p1, ConstClass(node_vtable)) [] + guard_nonnull(p1) [] guard_compatible(p1, ConstPtr(myptr)) [] jump(ConstPtr(myptr)) """ @@ -126,6 +126,37 @@ assert descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.myptr)) assert len(descr._compatibility_conditions.conditions) == 2 + def test_guard_compatible_call_pure_late_constant(self): + call_pure_results = { + (ConstInt(123), ConstPtr(self.myptr), ConstInt(5)): ConstInt(5), + (ConstInt(124), ConstPtr(self.myptr), ConstInt(5)): ConstInt(7), + } + ops = """ + [p1] + pvirtual = new_with_vtable(descr=nodesize) + setfield_gc(pvirtual, 5, descr=valuedescr) + i1 = getfield_gc_i(pvirtual, descr=valuedescr) + guard_compatible(p1, ConstPtr(myptr)) [] + i3 = call_pure_i(123, p1, i1, descr=plaincalldescr) + escape_n(i3) + i5 = call_pure_i(124, p1, i1, descr=plaincalldescr) + escape_n(i5) + jump(ConstPtr(myptr)) + """ + expected = """ + [p1] + guard_compatible(p1, ConstPtr(myptr)) [] + escape_n(5) + escape_n(7) + jump(ConstPtr(myptr)) + """ + self.optimize_loop(ops, expected, call_pure_results=call_pure_results) + # whitebox-test the guard_compatible descr a bit + descr = self.loop.operations[1].getdescr() + assert descr._compatibility_conditions is not None + assert descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.myptr)) + assert len(descr._compatibility_conditions.conditions) == 2 + def test_deduplicate_conditions(self): call_pure_results = { (ConstInt(123), ConstPtr(self.myptr)): ConstInt(5), diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -384,7 +384,7 @@ so its consquences are reflected into jitted code """ # during testing we return something randomly, to emulate the real # behaviour where you can switch to tracing a arbitrary points. - return random.random() > 0.5 + return False _we_are_jitted = CDefinedIntSymbolic('0 /* we are not jitted here */', default=0) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit