Author: Maciej Fijalkowski <fij...@gmail.com> Branch: share-guard-info Changeset: r79743:42f7b1bd660b Date: 2015-09-21 19:59 +0200 http://bitbucket.org/pypy/pypy/changeset/42f7b1bd660b/
Log: fight a bit with overflows, codewriter level diff --git a/rpython/jit/codewriter/flatten.py b/rpython/jit/codewriter/flatten.py --- a/rpython/jit/codewriter/flatten.py +++ b/rpython/jit/codewriter/flatten.py @@ -1,4 +1,4 @@ -from rpython.flowspace.model import Variable, Constant +from rpython.flowspace.model import Variable, Constant, c_last_exception from rpython.jit.metainterp.history import AbstractDescr, getkind from rpython.rtyper.lltypesystem import lltype @@ -114,6 +114,12 @@ # operations = block.operations for i, op in enumerate(operations): + if '_ovf' in op.opname: + if (len(block.exits) != 2 or + block.exitswitch is not c_last_exception): + raise Exception("detected a block containing ovfcheck()" + " but no OverflowError is caught, this" + " is not legal in jitted blocks") self.serialize_op(op) # self.insert_exits(block) @@ -171,11 +177,24 @@ # An exception block. See test_exc_exitswitch in test_flatten.py # for an example of what kind of code this makes. index = -1 - while True: - lastopname = block.operations[index].opname - if lastopname != '-live-': - break - index -= 1 + opname = block.operations[index].opname + if '_ovf' in opname: + # ovf checking operation as a lat thing, -live- should be + # one before it + line = self.popline() + self.emitline(opname[:7] + '_jump_if_ovf', + TLabel(block.exits[1]), *line[1:]) + assert len(block.exits) == 2 + self.make_link(block.exits[0]) + self.emitline(Label(block.exits[1])) + self.make_exception_link(block.exits[1]) + return + else: + while True: + lastopname = block.operations[index].opname + if lastopname != '-live-': + break + index -= 1 assert block.exits[0].exitcase is None # is this always True? # if not self._include_all_exc_links: @@ -189,10 +208,7 @@ self.make_link(block.exits[0]) self.emitline(Label(block.exits[0])) for link in block.exits[1:]: - if (link.exitcase is Exception or - (link.exitcase is OverflowError and - lastopname.startswith('int_') and - lastopname.endswith('_ovf'))): + if link.exitcase is Exception: # this link captures all exceptions self.make_exception_link(link) break @@ -320,6 +336,9 @@ def emitline(self, *line): self.ssarepr.insns.append(line) + def popline(self): + return self.ssarepr.insns.pop() + def flatten_list(self, arglist): args = [] for v in arglist: diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -8,7 +8,8 @@ from rpython.jit.metainterp.history import getkind from rpython.jit.metainterp.typesystem import deref, arrayItem from rpython.jit.metainterp.blackhole import BlackholeInterpreter -from rpython.flowspace.model import SpaceOperation, Variable, Constant +from rpython.flowspace.model import SpaceOperation, Variable, Constant,\ + c_last_exception from rpython.rlib import objectmodel from rpython.rlib.jit import _we_are_jitted from rpython.rlib.rgc import lltype_is_gc @@ -333,13 +334,13 @@ def rewrite_op_int_add_ovf(self, op): op0 = self._rewrite_symmetric(op) op1 = SpaceOperation('-live-', [], None) - return [op0, op1] + return [op1, op0] rewrite_op_int_mul_ovf = rewrite_op_int_add_ovf def rewrite_op_int_sub_ovf(self, op): op1 = SpaceOperation('-live-', [], None) - return [op, op1] + return [op1, op] def _noop_rewrite(self, op): return op diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -538,15 +538,44 @@ except OverflowError: return 42 self.encoding_test(f, [7, 2], """ - int_add_ovf %i0, %i1 -> %i2 - -live- %i2 - catch_exception L1 + -live- %i0, %i1 + int_add_jump_if_ovf L1, %i0, %i1 -> %i2 int_return %i2 --- L1: int_return $42 """, transform=True, liveness=True) + def test_multiple_int_add_ovf(self): + def f(i, j): + try: + ovfcheck(j + i) + return ovfcheck(i + j) + except OverflowError: + return 42 + self.encoding_test(f, [7, 2], """ + -live- %i0, %i1 + int_add_jump_if_ovf L1, %i1, %i0 -> %i2 + int_copy %i1 -> %i3 + int_copy %i0 -> %i4 + -live- %i3, %i4 + int_add_jump_if_ovf L2, %i4, %i3 -> %i5 + int_return %i5 + --- + L2: + int_return $42 + --- + L1: + int_return $42 + """, transform=True, liveness=True) + + def test_ovfcheck_no_catch(self): + def f(i, j): + return ovfcheck(i + j) + err = py.test.raises(Exception, "self.encoding_test(f, [7, 2], ''," + "transform=True, liveness=True)") + assert "ovfcheck()" in str(err) + def test_residual_call_raising(self): @dont_look_inside def g(i, j): diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -15,7 +15,7 @@ for prod in result: yield tuple(prod) -from rpython.flowspace.model import FunctionGraph, Block, Link +from rpython.flowspace.model import FunctionGraph, Block, Link, c_last_exception from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi from rpython.rtyper import rclass @@ -287,7 +287,7 @@ for v2 in [varoftype(lltype.Signed), const(43)]: op = SpaceOperation('int_add_nonneg_ovf', [v1, v2], v3) oplist = Transformer(FakeCPU()).rewrite_operation(op) - op0, op1 = oplist + op1, op0 = oplist assert op0.opname == 'int_add_ovf' if isinstance(v1, Constant) and isinstance(v2, Variable): assert op0.args == [v2, v1] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit