Author: Armin Rigo <ar...@tunes.org>
Branch: remove-raisingops
Changeset: r84287:ac5d871e304d
Date: 2016-05-08 17:33 +0200
http://bitbucket.org/pypy/pypy/changeset/ac5d871e304d/

Log:    Add an oopspec to turn divisions into "int_py_div" in the JIT
        frontend. The plan is to keep them as "int_py_div", and rewrite them
        in the end to "int_c_div".

diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1444,7 +1444,7 @@
         self.mov(imm0, resloc)
         self.mc.CMOVNS(resloc, arglocs[0])
 
-    def genop_int_mod(self, op, arglocs, resloc):
+    def genop_int_c_mod(self, op, arglocs, resloc):
         if IS_X86_32:
             self.mc.CDQ()
         elif IS_X86_64:
@@ -1452,7 +1452,7 @@
 
         self.mc.IDIV_r(ecx.value)
 
-    genop_int_floordiv = genop_int_mod
+    genop_int_c_div = genop_int_c_mod
 
     def genop_uint_floordiv(self, op, arglocs, resloc):
         self.mc.XOR_rr(edx.value, edx.value)
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -598,15 +598,15 @@
         assert l2 is resultreg
         self.rm.possibly_free_var(tmpvar)
 
-    def consider_int_mod(self, op):
+    def consider_int_c_mod(self, op):
         self._consider_int_div_or_mod(op, edx, eax)
         self.perform(op, [eax, ecx], edx)
 
-    def consider_int_floordiv(self, op):
+    def consider_int_c_div(self, op):
         self._consider_int_div_or_mod(op, eax, edx)
         self.perform(op, [eax, ecx], eax)
 
-    consider_uint_floordiv = consider_int_floordiv
+    consider_uint_floordiv = consider_int_c_div
 
     def _consider_compop(self, op):
         vx = op.getarg(0)
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
@@ -1903,12 +1903,15 @@
         self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func)
 
     def _handle_int_ovf(self, op, oopspec_name, args):
-        assert oopspec_name in ('int.add_ovf', 'int.sub_ovf', 'int.mul_ovf')
+        assert oopspec_name in ('int.add_ovf', 'int.sub_ovf', 'int.mul_ovf',
+                                'int.py_div', 'int.py_mod')
         op0 = SpaceOperation(oopspec_name.replace('.', '_'), args, op.result)
-        if oopspec_name != 'int.sub_ovf':
+        if oopspec_name in ('int.add_ovf', 'int.mul_ovf'):
             op0 = self._rewrite_symmetric(op0)
-        oplive = SpaceOperation('-live-', [], None)
-        return [oplive, op0]
+        oplist = [op0]
+        if oopspec_name.endswith('_ovf'):
+            oplist.insert(0, SpaceOperation('-live-', [], None))
+        return oplist
 
     def _handle_stroruni_call(self, op, oopspec_name, args):
         SoU = args[0].concretetype     # Ptr(STR) or Ptr(UNICODE)
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
@@ -268,15 +268,16 @@
                     assert op1.result == v3
                     assert op1.opname == name2[0]
 
-def test_symmetric_int_add_ovf():
+@py.test.mark.parametrize('opname', ['add_ovf', 'mul_ovf'])
+def test_symmetric_op_ovf(opname):
     v3 = varoftype(lltype.Signed)
     for v1 in [varoftype(lltype.Signed), const(42)]:
         for v2 in [varoftype(lltype.Signed), const(43)]:
             op = SpaceOperation('foobar', [v1, v2], v3)
-            oplist = Transformer(FakeCPU())._handle_int_ovf(op, 'int.add_ovf',
+            oplist = Transformer(FakeCPU())._handle_int_ovf(op, 'int.'+opname,
                                                             [v1, v2])
             op1, op0 = oplist
-            assert op0.opname == 'int_add_ovf'
+            assert op0.opname == 'int_'+opname
             if isinstance(v1, Constant) and isinstance(v2, Variable):
                 assert op0.args == [v2, v1]
                 assert op0.result == v3
@@ -287,6 +288,35 @@
             assert op1.args == []
             assert op1.result is None
 
+@py.test.mark.parametrize('opname', ['sub_ovf'])
+def test_asymmetric_op_ovf(opname):
+    v3 = varoftype(lltype.Signed)
+    for v1 in [varoftype(lltype.Signed), const(42)]:
+        for v2 in [varoftype(lltype.Signed), const(43)]:
+            op = SpaceOperation('foobar', [v1, v2], v3)
+            oplist = Transformer(FakeCPU())._handle_int_ovf(op, 'int.'+opname,
+                                                            [v1, v2])
+            op1, op0 = oplist
+            assert op0.opname == 'int_'+opname
+            assert op0.args == [v1, v2]
+            assert op0.result == v3
+            assert op1.opname == '-live-'
+            assert op1.args == []
+            assert op1.result is None
+
+@py.test.mark.parametrize('opname', ['py_div', 'py_mod'])
+def test_asymmetric_op_nonovf(opname):
+    v3 = varoftype(lltype.Signed)
+    for v1 in [varoftype(lltype.Signed), const(42)]:
+        for v2 in [varoftype(lltype.Signed), const(43)]:
+            op = SpaceOperation('foobar', [v1, v2], v3)
+            oplist = Transformer(FakeCPU())._handle_int_ovf(op, 'int.'+opname,
+                                                            [v1, v2])
+            [op0] = oplist
+            assert op0.opname == 'int_'+opname
+            assert op0.args == [v1, v2]
+            assert op0.result == v3
+
 def test_calls():
     for RESTYPE, with_void, with_i, with_r, with_f in product(
         [lltype.Signed, rclass.OBJECTPTR, lltype.Float, lltype.Void],
diff --git a/rpython/jit/metainterp/blackhole.py 
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -430,8 +430,8 @@
             return 0, label
 
     @arguments("i", "i", returns="i")
-    def bhimpl_int_floordiv(a, b):
-        return llop.int_floordiv(lltype.Signed, a, b)
+    def bhimpl_int_py_div(a, b):
+        return a // b
 
     @arguments("i", "i", returns="i")
     def bhimpl_uint_floordiv(a, b):
@@ -439,8 +439,8 @@
         return intmask(c)
 
     @arguments("i", "i", returns="i")
-    def bhimpl_int_mod(a, b):
-        return llop.int_mod(lltype.Signed, a, b)
+    def bhimpl_int_py_mod(a, b):
+        return a % b
 
     @arguments("i", "i", returns="i")
     def bhimpl_int_and(a, b):
diff --git a/rpython/jit/metainterp/executor.py 
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -409,6 +409,8 @@
                          rop.GC_STORE,
                          rop.GC_STORE_INDEXED,
                          rop.LOAD_FROM_GC_TABLE,
+                         rop.INT_C_DIV,
+                         rop.INT_C_MOD,
                          ):      # list of opcodes never executed by pyjitpl
                 continue
             if rop._VEC_PURE_FIRST <= value <= rop._VEC_PURE_LAST:
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -201,7 +201,7 @@
 
     # ------------------------------
 
-    for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod',
+    for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_py_div', 
'int_py_mod',
                     'int_and', 'int_or', 'int_xor', 'int_signext',
                     'int_rshift', 'int_lshift', 'uint_rshift',
                     'uint_lt', 'uint_le', 'uint_gt', 'uint_ge',
diff --git a/rpython/jit/metainterp/resoperation.py 
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -955,9 +955,11 @@
     'INT_ADD/2/i',
     'INT_SUB/2/i',
     'INT_MUL/2/i',
-    'INT_FLOORDIV/2/i',
+    'INT_C_DIV/2/i',      # C-style handling of negatives (backend only)
+    'INT_PY_DIV/2/i',     # Python-style handling of negatives (frontend)
     'UINT_FLOORDIV/2/i',
-    'INT_MOD/2/i',
+    'INT_C_MOD/2/i',      # C-style handling of negatives (backend only)
+    'INT_PY_MOD/2/i',     # Python-style handling of negatives (frontend)
     'INT_AND/2/i',
     'INT_OR/2/i',
     'INT_XOR/2/i',
diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -601,7 +601,7 @@
         policy = StopAtXPolicy(externfn)
         res = self.meta_interp(f, [31], policy=policy)
         assert res == 42
-        self.check_resops(int_mul=2, int_mod=0)
+        self.check_resops(int_mul=2, int_py_mod=0, int_c_mod=0)
 
     def test_we_are_jitted(self):
         myjitdriver = JitDriver(greens = [], reds = ['y'])
diff --git a/rpython/jit/metainterp/test/test_dict.py 
b/rpython/jit/metainterp/test/test_dict.py
--- a/rpython/jit/metainterp/test/test_dict.py
+++ b/rpython/jit/metainterp/test/test_dict.py
@@ -117,7 +117,7 @@
         res1 = f(100)
         res2 = self.meta_interp(f, [100], listops=True)
         assert res1 == res2
-        self.check_resops(int_mod=2) # the hash was traced and eq, but cached
+        self.check_resops(int_py_mod=2) # the hash was traced and eq, but 
cached
 
     def test_dict_setdefault(self):
         myjitdriver = JitDriver(greens = [], reds = ['total', 'dct'])
@@ -156,7 +156,7 @@
         assert f(100) == 50
         res = self.meta_interp(f, [100], listops=True)
         assert res == 50
-        self.check_resops(int_mod=2) # key + eq, but cached
+        self.check_resops(int_py_mod=2) # key + eq, but cached
 
     def test_repeated_lookup(self):
         if type(self.newdict()) is not dict:
diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py
--- a/rpython/rtyper/rint.py
+++ b/rpython/rtyper/rint.py
@@ -382,6 +382,7 @@
 
 # ---------- floordiv ----------
 
+@jit.oopspec("int.py_div(x, y)")
 def ll_int_floordiv(x, y):
     # Python, and RPython, assume that integer division truncates
     # towards -infinity.  However, in C, integer division truncates
@@ -447,6 +448,7 @@
 
 # ---------- mod ----------
 
+@jit.oopspec("int.py_mod(x, y)")
 def ll_int_mod(x, y):
     r = llop.int_mod(Signed, x, y)                 # <= truncates like in C
     if y < 0: u = -r
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to