[pypy-commit] pypy default: Issue #2015 second attempt: don't put 'call_pure' in short preamble, not
arigo
noreply at buildbot.pypy.org
Fri Apr 3 17:02:07 CEST 2015
Author: Armin Rigo <arigo at 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)
More information about the pypy-commit
mailing list