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

arigo at codespeak.net arigo at codespeak.net
Tue Apr 27 15:56:31 CEST 2010


Author: arigo
Date: Tue Apr 27 15:56:30 2010
New Revision: 74111

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
Log:
Add the operation 'goto_if_not_int_is_true'.


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	Tue Apr 27 15:56:30 2010
@@ -1,6 +1,7 @@
 from pypy.rpython.lltypesystem import lltype, rstr
 from pypy.jit.metainterp.history import getkind
-from pypy.objspace.flow.model import SpaceOperation, Variable, c_last_exception
+from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
+from pypy.objspace.flow.model import c_last_exception
 from pypy.jit.codewriter.flatten import ListOfKind
 
 
@@ -84,11 +85,25 @@
                 return False   # variable is also used in cur block
             if v is op.result:
                 if op.opname not in ('int_lt', 'int_le', 'int_eq', 'int_ne',
-                                     'int_gt', 'int_ge'):
+                                     'int_gt', 'int_ge', 'int_is_true'):
                     return False    # not a supported operation
                 # ok! optimize this case
                 block.operations.remove(op)
-                block.exitswitch = (op.opname,) + tuple(op.args)
+                opname = op.opname
+                args = op.args
+                if op.opname in ('int_ne', 'int_eq'):
+                    if isinstance(args[0], Constant):
+                        args = args[::-1]
+                    if isinstance(args[1], Constant) and args[1].value == 0:
+                        if opname == 'int_eq':
+                            # must invert the two exit links
+                            link = block.exits[0]
+                            link.llexitcase = link.exitcase = not link.exitcase
+                            link = block.exits[1]
+                            link.llexitcase = link.exitcase = not link.exitcase
+                        opname = 'int_is_true'
+                        args = [args[0]]
+                block.exitswitch = (opname,) + tuple(args)
                 return True
         return False
 

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	Tue Apr 27 15:56:30 2010
@@ -8,6 +8,7 @@
 from pypy.rpython.lltypesystem import lltype, rclass, rstr
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
 from pypy.translator.unsimplify import varoftype
+from pypy.rlib.rarithmetic import ovfcheck
 
 
 class FakeRegAlloc:
@@ -243,17 +244,17 @@
                 return 3
 
         self.encoding_test(f, [65], """
-        direct_call $<* fn g>, %i0
-        catch_exception L1
-        int_return $3
-        L1:
-        goto_if_exception_mismatch $<* struct object_vtable>, L2
-        int_return $1
-        L2:
-        goto_if_exception_mismatch $<* struct object_vtable>, L3
-        int_return $2
-        L3:
-        reraise
+            direct_call $<* fn g>, %i0
+            catch_exception L1
+            int_return $3
+            L1:
+            goto_if_exception_mismatch $<* struct object_vtable>, L2
+            int_return $1
+            L2:
+            goto_if_exception_mismatch $<* struct object_vtable>, L3
+            int_return $2
+            L3:
+            reraise
         """)
 
     def test_exc_exitswitch_2(self):
@@ -273,17 +274,17 @@
                 return 4
 
         self.encoding_test(f, [65], """
-        residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
-        catch_exception L1
-        int_return $4
-        L1:
-        goto_if_exception_mismatch $<* struct object_vtable>, L2
-        last_exc_value %r0
-        ref_copy %r0, %r1
-        getfield_gc_i %r1, <Descr>, %i1
-        int_return %i1
-        L2:
-        int_return $3
+            residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+            catch_exception L1
+            int_return $4
+            L1:
+            goto_if_exception_mismatch $<* struct object_vtable>, L2
+            last_exc_value %r0
+            ref_copy %r0, %r1
+            getfield_gc_i %r1, <Descr>, %i1
+            int_return %i1
+            L2:
+            int_return $3
         """, transform=True)
 
     def test_exc_raise_1(self):
@@ -307,9 +308,41 @@
                 raise KeyError
 
         self.encoding_test(f, [65], """
-        direct_call $<* fn g>, %i0
-        catch_exception L1
-        void_return
-        L1:
-        raise $<* struct object>
+            direct_call $<* fn g>, %i0
+            catch_exception L1
+            void_return
+            L1:
+            raise $<* struct object>
         """)
+
+    def test_goto_if_not_int_is_true(self):
+        def f(i):
+            return not i
+
+        self.encoding_test(f, [7], """
+            goto_if_not_int_is_true L1, %i0
+            int_return $False
+            L1:
+            int_return $True
+        """, transform=True)
+
+    def test_int_floordiv_ovf_zer(self):
+        py.test.skip("in-progress")
+        def f(i, j):
+            try:
+                return ovfcheck(i // j)
+            except OverflowError:
+                return 42
+            except ZeroDivisionError:
+                return -42
+
+        self.encoding_test(f, [7, 2], """
+            goto_if_not_int_is_true L1, %i1
+            goto_if_div_overflow L2, %i0, %i1
+            int_floordiv %i0, %i1, %i0
+            int_return %i0
+            L1:
+            int_return $-42
+            L2:
+            int_return $42
+        """, transform=True)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	Tue Apr 27 15:56:30 2010
@@ -14,6 +14,8 @@
 
 class FakeLink:
     args = []
+    def __init__(self, exitcase):
+        self.exitcase = self.llexitcase = exitcase
 
 def test_optimize_goto_if_not():
     v1 = Variable()
@@ -24,7 +26,7 @@
     block = Block([v1, v2])
     block.operations = [sp1, SpaceOperation('int_gt', [v1, v2], v3), sp2]
     block.exitswitch = v3
-    block.exits = exits = [FakeLink(), FakeLink()]
+    block.exits = exits = [FakeLink(False), FakeLink(True)]
     res = Transformer().optimize_goto_if_not(block)
     assert res == True
     assert block.operations == [sp1, sp2]
@@ -35,7 +37,7 @@
     v1 = Variable(); v1.concretetype = lltype.Bool
     block = Block([v1])
     block.exitswitch = v1
-    block.exits = [FakeLink(), FakeLink()]
+    block.exits = [FakeLink(False), FakeLink(True)]
     assert not Transformer().optimize_goto_if_not(block)
 
 def test_optimize_goto_if_not__exit():
@@ -45,7 +47,7 @@
     block = Block([v1, v2])
     block.operations = [SpaceOperation('int_gt', [v1, v2], v3)]
     block.exitswitch = v3
-    block.exits = [FakeLink(), FakeLink()]
+    block.exits = [FakeLink(False), FakeLink(True)]
     block.exits[1].args = [v3]
     assert not Transformer().optimize_goto_if_not(block)
 
@@ -54,9 +56,35 @@
     block = Block([])
     block.operations = [SpaceOperation('foobar', [], v3)]
     block.exitswitch = v3
-    block.exits = [FakeLink(), FakeLink()]
+    block.exits = [FakeLink(False), FakeLink(True)]
     assert not Transformer().optimize_goto_if_not(block)
 
+def test_optimize_goto_if_not__int_ne():
+    c0 = Constant(0, lltype.Signed)
+    v1 = Variable()
+    v3 = Variable(); v3.concretetype = lltype.Bool
+    for linkcase1 in [False, True]:
+        linkcase2 = not linkcase1
+        for op, args in [('int_ne', [v1, c0]),
+                         ('int_ne', [c0, v1]),
+                         ('int_eq', [v1, c0]),
+                         ('int_eq', [c0, v1])]:
+            block = Block([v1])
+            block.operations = [SpaceOperation(op, args, v3)]
+            block.exitswitch = v3
+            block.exits = exits = [FakeLink(linkcase1), FakeLink(linkcase2)]
+            res = Transformer().optimize_goto_if_not(block)
+            assert res == True
+            assert block.operations == []
+            assert block.exitswitch == ('int_is_true', v1)
+            assert block.exits == exits
+            if op == 'int_ne':
+                assert exits[0].exitcase == exits[0].llexitcase == linkcase1
+                assert exits[1].exitcase == exits[1].llexitcase == linkcase2
+            else:
+                assert exits[0].exitcase == exits[0].llexitcase == linkcase2
+                assert exits[1].exitcase == exits[1].llexitcase == linkcase1
+
 def test_residual_call():
     for RESTYPE in [lltype.Signed, rclass.OBJECTPTR,
                     lltype.Float, lltype.Void]:



More information about the Pypy-commit mailing list