[pypy-svn] r74152 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 28 10:39:33 CEST 2010


Author: arigo
Date: Wed Apr 28 10:39:31 2010
New Revision: 74152

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
Log:
Give up on the complicated graph mangling code in jitter.py
and instead just replace 'int_{floordiv,mod}_ovf_zer' with
a call to a helper function.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	Wed Apr 28 10:39:31 2010
@@ -131,9 +131,14 @@
 
     def make_exception_link(self, link):
         # Like make_link(), but also introduces the 'last_exception' and
-        # 'last_exc_value' as variables if needed
+        # 'last_exc_value' as variables if needed.  Also check if the link
+        # is jumping directly to the re-raising exception block.
         assert link.last_exception is not None
         assert link.last_exc_value is not None
+        if link.target.operations == () and link.args == [link.last_exception,
+                                                          link.last_exc_value]:
+            self.emitline("reraise")
+            return   # done
         if link.last_exception in link.args:
             self.emitline("last_exception", self.getcolor(link.last_exception))
         if link.last_exc_value in link.args:
@@ -157,13 +162,7 @@
             for link in block.exits[1:]:
                 if link.exitcase is Exception:
                     # this link captures all exceptions
-                    if (link.target.operations == ()
-                        and link.args == [link.last_exception,
-                                          link.last_exc_value]):
-                        # the link is going directly to the except block
-                        self.emitline("reraise")
-                    else:
-                        self.make_exception_link(link)
+                    self.make_exception_link(link)
                     break
                 self.emitline('goto_if_exception_mismatch',
                               Constant(link.llexitcase,

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	Wed Apr 28 10:39:31 2010
@@ -35,7 +35,6 @@
         newoperations = []
         if block.exitswitch == c_last_exception:
             op_raising_exception = block.operations[-1]
-            self.rewrite_exception_operation(op_raising_exception, block)
         else:
             op_raising_exception = Ellipsis
         for op in block.operations:
@@ -123,82 +122,6 @@
 
     # ----------
 
-    def rewrite_exception_operation(self, op, block):
-        # mangling of the graph for exception-raising operations that are
-        # not simple calls
-        try:
-            rewrite = _rewrite_exc_ops[op.opname]
-        except KeyError:
-            pass
-        else:
-            rewrite(self, op, block)
-
-    def _rewrite_exc_div_or_mod_ovf_zer(self, op, block):
-        # See test_flatten.test_int_floordiv_ovf_zer for the mangling done here
-        usedvars = self.list_vars_in_use_at_end(block, op.args, op.result)
-        block.operations.pop()
-        [ovf_link, zer_link] = self.extract_exc_links(block, [
-            OverflowError, ZeroDivisionError])
-        block = self.write_new_condition(block, usedvars, zer_link,
-                                         ('int_is_true', op.args[1]))
-        v1 = Variable(); v1.concretetype = lltype.Signed
-        v2 = Variable(); v2.concretetype = lltype.Signed
-        block.operations += [
-            SpaceOperation('int_add', [op.args[0],
-                                       Constant(sys.maxint, lltype.Signed)],
-                           v1),
-            SpaceOperation('int_and', [v1, op.args[1]], v2),
-            ]
-        block = self.write_new_condition(block, usedvars, ovf_link,
-                                 ('int_ne', v2, Constant(-1, lltype.Signed)))
-        basename = op.opname.split('_')[1]
-        block.operations += [
-            SpaceOperation('int_' + basename, op.args, op.result),
-            ]
-
-    rewrite_exc_op_int_floordiv_ovf_zer = _rewrite_exc_div_or_mod_ovf_zer
-    rewrite_exc_op_int_mod_ovf_zer      = _rewrite_exc_div_or_mod_ovf_zer
-
-    def list_vars_in_use_at_end(self, block, extravars=[], exclude=None):
-        lists = [extravars]
-        for link in block.exits:
-            lists.append(link.args)
-        in_use = set()
-        for lst in lists:
-            for v in lst:
-                if isinstance(v, Variable):
-                    in_use.add(v)
-        if exclude in in_use:
-            in_use.remove(exclude)
-        return list(in_use)
-
-    def extract_exc_links(self, block, exceptions):
-        # Remove the exception links from the block.  The exception links must
-        # be catching exactly the listed 'exceptions'.  We return them to the
-        # caller.
-        assert block.exits[0].exitcase is None
-        real_exc_links = dict([(link.exitcase, link)
-                               for link in block.exits[1:]])
-        assert dict.fromkeys(real_exc_links) == dict.fromkeys(exceptions)
-        block.recloseblock(block.exits[0])
-        return [real_exc_links[exc] for exc in exceptions]
-
-    def write_new_condition(self, block, usedvars, exc_link, exitswitch):
-        # Write an exit at the end of the block, going either to a new
-        # block that is the continuation of the current block, or (in case
-        # 'exitswitch' is False) following the given 'exc_link'.
-        newblock = Block(usedvars)
-        normal_link = Link(usedvars, newblock)
-        normal_link.exitcase = normal_link.llexitcase = True
-        exc_link.exitcase    = exc_link.llexitcase    = False
-        block.exitswitch = exitswitch
-        [exit] = block.exits
-        block.recloseblock(normal_link, exc_link)
-        newblock.closeblock(exit)
-        return newblock
-
-    # ----------
-
     def rewrite_operation(self, op):
         try:
             rewrite = _rewrite_ops[op.opname]
@@ -247,6 +170,21 @@
         else: raise AssertionError(kind)
         lst.append(v)
 
+    def _rewrite_with_helper(self, op):
+        from pypy.jit.codewriter.support import builtin_func_for_spec
+        c_func, _ = builtin_func_for_spec(self.cpu.rtyper, op.opname,
+                                          [lltype.Signed, lltype.Signed],
+                                          lltype.Signed)
+        op = SpaceOperation('direct_call', [c_func] + op.args, op.result)
+        return self.rewrite_op_direct_call(op)
+
+    rewrite_op_int_floordiv_ovf_zer = _rewrite_with_helper
+    rewrite_op_int_floordiv_ovf     = _rewrite_with_helper
+    rewrite_op_int_floordiv_zer     = _rewrite_with_helper
+    rewrite_op_int_mod_ovf_zer = _rewrite_with_helper
+    rewrite_op_int_mod_ovf     = _rewrite_with_helper
+    rewrite_op_int_mod_zer     = _rewrite_with_helper
+
     def rewrite_op_hint(self, op):
         hints = op.args[1].value
         if hints.get('promote') and op.args[0].concretetype is not lltype.Void:
@@ -351,8 +289,7 @@
             result[name[len(prefix):]] = getattr(Transformer, name)
     return result
 
-_rewrite_ops     = _with_prefix('rewrite_op_')
-_rewrite_exc_ops = _with_prefix('rewrite_exc_op_')
+_rewrite_ops = _with_prefix('rewrite_op_')
 
 primitive_type_size = {
     lltype.Signed:   'i',

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	Wed Apr 28 10:39:31 2010
@@ -143,6 +143,20 @@
 def _ll_1_jit_force_virtual(inst):
     return llop.jit_force_virtual(lltype.typeOf(inst), inst)
 
+def _ll_2_int_floordiv_ovf_zer(x, y):
+    return llop.int_floordiv_ovf_zer(lltype.Signed, x, y)
+def _ll_2_int_floordiv_ovf(x, y):
+    return llop.int_floordiv_ovf(lltype.Signed, x, y)
+def _ll_2_int_floordiv_zer(x, y):
+    return llop.int_floordiv_zer(lltype.Signed, x, y)
+
+def _ll_2_int_mod_ovf_zer(x, y):
+    return llop.int_mod_ovf_zer(lltype.Signed, x, y)
+def _ll_2_int_mod_ovf(x, y):
+    return llop.int_mod_ovf(lltype.Signed, x, y)
+def _ll_2_int_mod_zer(x, y):
+    return llop.int_mod_zer(lltype.Signed, x, y)
+
 
 class LLtypeHelpers:
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	Wed Apr 28 10:39:31 2010
@@ -26,7 +26,18 @@
     def __repr__(self):
         return '<Descr>'
 
+class FakeDict(object):
+    def __getitem__(self, key):
+        F = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
+        f = lltype.functionptr(F, key[0])
+        c_func = Constant(f, lltype.typeOf(f))
+        return c_func, lltype.Signed
+
+class FakeRTyper(object):
+    _builtin_func_for_spec_cache = FakeDict()
+
 class FakeCPU:
+    rtyper = FakeRTyper()
     def calldescrof(self, FUNC, ARGS, RESULT):
         return FakeDescr()
     def fielddescrof(self, STRUCT, name):
@@ -338,17 +349,53 @@
                 return 42
             except ZeroDivisionError:
                 return -42
-        # 'int_add' and 'int_and' are used to detect the
-        # combination "%i0 = -sys.maxint-1, %i1 = -1".
         self.encoding_test(f, [7, 2], """
-            goto_if_not_int_is_true L1, %i1
-            int_add %i0, $MAXINT, %i2
-            int_and %i2, %i1, %i3
-            goto_if_not_int_ne L2, %i3, $-1
-            int_floordiv %i0, %i1, %i4
-            int_return %i4
+            residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            catch_exception L1
+            int_return %i2
+            L1:
+            goto_if_exception_mismatch $<* struct object_vtable>, L2
+            int_return $42
             L2:
+            goto_if_exception_mismatch $<* struct object_vtable>, L3
+            int_return $-42
+            L3:
+            reraise
+        """, transform=True)
+
+    def test_int_mod_ovf(self):
+        def f(i, j):
+            assert i >= 0
+            assert j >= 0
+            try:
+                return ovfcheck(i % j)
+            except OverflowError:
+                return 42
+        # XXX so far, this really produces a int_mod_ovf_zer...
+        self.encoding_test(f, [7, 2], """
+            residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+            catch_exception L1
+            int_return %i2
+            L1:
+            goto_if_exception_mismatch $<* struct object_vtable>, L2
             int_return $42
+            L2:
+            reraise
+        """, transform=True)
+
+    def test_int_add_ovf(self):
+        def f(i, j):
+            try:
+                return ovfcheck(i + j)
+            except OverflowError:
+                return 42
+        self.encoding_test(f, [7, 2], """
+            int_add_ovf %i0, %i1, %i2
+            catch_exception L1
+            int_return %i2
             L1:
-            int_return $-42
-        """.replace('MAXINT', str(sys.maxint)), transform=True)
+            goto_if_exception_mismatch $<* struct object_vtable>, L2
+            int_return $42
+            L2:
+            reraise
+        """, transform=True)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	Wed Apr 28 10:39:31 2010
@@ -180,27 +180,3 @@
             L2:
             reraise
         """)
-
-    def test_int_floordiv_ovf_zer(self):
-        def f(i, j):
-            assert i >= 0
-            assert j >= 0
-            try:
-                return ovfcheck(i // j)
-            except OverflowError:
-                return 42
-            except ZeroDivisionError:
-                return -42
-        graph = self.make_graphs(f, [5, 6])[0]
-        self.check_assembler(graph, """
-            goto_if_not_int_is_true L1, %i1
-            int_add %i0, $MAXINT, %i2
-            int_and %i2, %i1, %i2
-            goto_if_not_int_ne L2, %i2, $-1
-            int_floordiv %i0, %i1, %i0
-            int_return %i0
-            L2:
-            int_return $42
-            L1:
-            int_return $-42
-        """.replace('MAXINT', str(sys.maxint)), transform=True)



More information about the Pypy-commit mailing list