[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