Author: Armin Rigo <[email protected]>
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():
[email protected]('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
[email protected]('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
+
[email protected]('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 ----------
[email protected]("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 ----------
[email protected]("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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit