[pypy-commit] pypy share-guard-info: fight a bit with overflows, codewriter level
fijal
noreply at buildbot.pypy.org
Mon Sep 21 20:05:18 CEST 2015
Author: Maciej Fijalkowski <fijall at 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]
More information about the pypy-commit
mailing list