Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r76701:56eebe9dd813 Date: 2015-04-03 15:28 +0200 http://bitbucket.org/pypy/pypy/changeset/56eebe9dd813/
Log: Issue #2015 second attempt: don't put 'call_pure' in short preamble, not at all, if they can raise. I *think* the issue is that an exception that we'd get then would be propagated outside, uncaught. 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 @@ -80,7 +80,13 @@ args = op.getarglist() self.emit_operation(ResOperation(rop.CALL, args, op.result, op.getdescr())) - self.call_pure_positions.append(len(self.optimizer._newoperations) - 1) + + # don't move call_pure_with_exception in the short preamble... + # issue #2015 + effectinfo = op.getdescr().get_extra_info() + if not effectinfo.check_can_raise(): + self.call_pure_positions.append( + len(self.optimizer._newoperations) - 1) def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -3605,7 +3605,7 @@ ops = ''' [p1, i1, i4] setfield_gc(p1, i1, descr=valuedescr) - i3 = call_pure(p1, descr=plaincalldescr) + i3 = call_pure(p1, descr=cannotraisecalldescr) setfield_gc(p1, i3, descr=valuedescr) jump(p1, i4, i3) ''' @@ -3617,7 +3617,7 @@ preamble = ''' [p1, i1, i4] setfield_gc(p1, i1, descr=valuedescr) - i3 = call(p1, descr=plaincalldescr) + i3 = call(p1, descr=cannotraisecalldescr) setfield_gc(p1, i3, descr=valuedescr) i148 = same_as(i3) i147 = same_as(i3) @@ -3630,7 +3630,7 @@ ops = ''' [p1, i1, i4] setfield_gc(p1, i1, descr=valuedescr) - i3 = call_pure(p1, descr=plaincalldescr) + i3 = call_pure(p1, descr=cannotraisecalldescr) setfield_gc(p1, i1, descr=valuedescr) jump(p1, i4, i3) ''' @@ -3642,7 +3642,7 @@ preamble = ''' [p1, i1, i4] setfield_gc(p1, i1, descr=valuedescr) - i3 = call(p1, descr=plaincalldescr) + i3 = call(p1, descr=cannotraisecalldescr) setfield_gc(p1, i1, descr=valuedescr) i151 = same_as(i3) jump(p1, i4, i3, i151) @@ -3656,15 +3656,15 @@ [i0, i1, i2] escape(i1) escape(i2) - i3 = call_pure(123456, 4, 5, 6, descr=plaincalldescr) - i4 = call_pure(123456, 4, i0, 6, descr=plaincalldescr) + i3 = call_pure(123456, 4, 5, 6, descr=cannotraisecalldescr) + i4 = call_pure(123456, 4, i0, 6, descr=cannotraisecalldescr) jump(i0, i3, i4) ''' preamble = ''' [i0, i1, i2] escape(i1) escape(i2) - i4 = call(123456, 4, i0, 6, descr=plaincalldescr) + i4 = call(123456, 4, i0, 6, descr=cannotraisecalldescr) i153 = same_as(i4) jump(i0, i4, i153) ''' @@ -3678,6 +3678,8 @@ def test_call_pure_constant_folding_exc(self): # CALL_PURE may be followed by GUARD_NO_EXCEPTION + # XXX maybe temporary, but we can't remove such call_pures from + # the loop, because the short preamble can't call them safely. arg_consts = [ConstInt(i) for i in (123456, 4, 5, 6)] call_pure_results = {tuple(arg_consts): ConstInt(42)} ops = ''' @@ -3696,14 +3698,15 @@ escape(i2) i4 = call(123456, 4, i0, 6, descr=plaincalldescr) guard_no_exception() [] - i155 = same_as(i4) - jump(i0, i4, i155) + jump(i0, i4) ''' expected = ''' - [i0, i2, i3] + [i0, i2] escape(42) escape(i2) - jump(i0, i3, i3) + i4 = call(123456, 4, i0, 6, descr=plaincalldescr) + guard_no_exception() [] + jump(i0, i4) ''' self.optimize_loop(ops, expected, preamble, call_pure_results) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py --- a/rpython/jit/metainterp/optimizeopt/test/test_util.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py @@ -182,6 +182,9 @@ FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) + cannotraisecalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([], [], [], [valuedescr], [], [], + EffectInfo.EF_CANNOT_RAISE)) nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [], [], [], [])) writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -438,9 +438,7 @@ if op.is_ovf(): guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) optimizer.send_extra_operation(guard) - if op.is_call_pure_with_exception(): - guard = ResOperation(rop.GUARD_NO_EXCEPTION, [], None) - optimizer.send_extra_operation(guard) + assert not op.is_call_pure_with_exception() def add_op_to_short(self, op, emit=True, guards_needed=False): if op is None: @@ -474,9 +472,7 @@ # FIXME: ensure that GUARD_OVERFLOW:ed ops not end up here guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) self.add_op_to_short(guard, emit, guards_needed) - if op.is_call_pure_with_exception(): - guard = ResOperation(rop.GUARD_NO_EXCEPTION, [], None) - self.add_op_to_short(guard, emit, guards_needed) + assert not op.is_call_pure_with_exception() for guard in value_guards: self.add_op_to_short(guard, emit, guards_needed) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit