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