[pypy-svn] r65804 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph backend/llvm backend/test backend/x86 metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Wed Jun 17 18:11:28 CEST 2009


Author: arigo
Date: Wed Jun 17 18:11:26 2009
New Revision: 65804

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py
   pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py
   pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py
Log:
Get rid of INT_LSHIFT_OVF and INT_NEG_OVF.  Implement them
instead directly in codewriter.py.

Add some XXX for broken code (next checkin...)


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	Wed Jun 17 18:11:26 2009
@@ -71,8 +71,6 @@
     'int_add_ovf'     : (('int', 'int'), 'int'),
     'int_sub_ovf'     : (('int', 'int'), 'int'),
     'int_mul_ovf'     : (('int', 'int'), 'int'),
-    'int_neg_ovf'     : (('int',), 'int'),
-    'int_lshift_ovf'  : (('int', 'int'), 'int'),
     'bool_not'        : (('bool',), 'bool'),
     'uint_add'        : (('int', 'int'), 'int'),
     'uint_sub'        : (('int', 'int'), 'int'),

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/compile.py	Wed Jun 17 18:11:26 2009
@@ -332,20 +332,6 @@
     def generate_INT_MUL_OVF(self, op):
         self._generate_ovf_op(op, self.cpu.f_mul_ovf)
 
-    def generate_INT_NEG_OVF(self, op):
-        self._generate_ovf_test(self.cpu.f_sub_ovf,
-                                self.cpu.const_zero,
-                                self.getintarg(op.args[0]),
-                                op.result)
-
-    def generate_INT_LSHIFT_OVF(self, op):
-        arg0 = self.getintarg(op.args[0])
-        arg1 = llvm_rffi.LLVMBuildShl(self.builder,
-                                      self.cpu.const_one,
-                                      self.getintarg(op.args[1]),
-                                      "")
-        self._generate_ovf_test(self.cpu.f_mul_ovf, arg0, arg1, op.result)
-
     def _generate_ovf_op(self, op, f_intrinsic):
         self._generate_ovf_test(f_intrinsic,
                                 self.getintarg(op.args[0]),

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner_test.py	Wed Jun 17 18:11:26 2009
@@ -209,14 +209,6 @@
             (rop.INT_MUL_OVF, [(minint/2, 2, minint),
                                (-2, -(minint/2), minint),
                                (minint/2, -2, boom)]),
-            (rop.INT_NEG_OVF, [(-sys.maxint, 0, sys.maxint),
-                               (sys.maxint, 0, -sys.maxint),
-                               (minint, 0, boom)]),
-            (rop.INT_LSHIFT_OVF, [(0x1f87611, 6, 0x7e1d8440),
-                                  (-0x1f87611, 6, -0x7e1d8440),
-                                  (sys.maxint//8+1, 3, boom),
-                                  (minint//2-1, 1, boom),
-                                  (0, 345, 0)]),
             ]:
             v1 = BoxInt(testcases[0][0])
             v2 = BoxInt(testcases[0][1])
@@ -247,8 +239,6 @@
                     ]
                 ops[1].suboperations = [ResOperation(rop.FAIL, [v_res], None)]
             #
-            if opnum == rop.INT_NEG_OVF:
-                del ops[0].args[1]
             loop = TreeLoop('name')
             loop.operations = ops
             loop.inputargs = [v1, v2]

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py	Wed Jun 17 18:11:26 2009
@@ -244,9 +244,6 @@
 class BinaryOvfOperation(AbstractOvfOperation, BinaryOperation):
     pass
 
-class UnaryOvfOperation(AbstractOvfOperation, UnaryOperation):
-    pass
-
 class GuardOperation(AbstractOperation):
     def gen_guard(self, builder, r):
         v = builder.get_bool_var(r)
@@ -328,12 +325,6 @@
             ]:
     OPERATIONS.append(BinaryOvfOperation(_op))
 
-OPERATIONS.append(BinaryOvfOperation(rop.INT_LSHIFT_OVF, LONG_BIT-1))
-
-for _op in [rop.INT_NEG_OVF,
-            ]:
-    OPERATIONS.append(UnaryOvfOperation(_op))
-
 OperationBuilder.OPERATIONS = OPERATIONS
 
 # ____________________________________________________________

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Wed Jun 17 18:11:26 2009
@@ -366,15 +366,6 @@
     genop_guard_int_sub_ovf = _binaryop_ovf("SUB")
     genop_guard_int_add_ovf = _binaryop_ovf("ADD", True)
 
-    def genop_guard_int_neg_ovf(self, op, guard_op, addr, arglocs, result_loc):
-        self.mc.NEG(result_loc)
-        if guard_op.opnum == rop.GUARD_NO_EXCEPTION:
-            self.mc.JO(rel32(addr))
-        elif guard_op.opnum == rop.GUARD_EXCEPTION:
-            self.mc.JNO(rel32(addr))
-        else:
-            raise AssertionError
-
     genop_int_lt = _cmpop("L", "G")
     genop_int_le = _cmpop("LE", "GE")
     genop_int_eq = _cmpop("E", "E")
@@ -426,27 +417,6 @@
             loc2 = cl
         self.mc.SHR(loc, loc2)
 
-    def genop_guard_int_lshift_ovf(self, op, guard_op, addr, arglocs, resloc):
-        loc, loc2, tmploc = arglocs
-        if loc2 is ecx:
-            loc2 = cl
-        # xxx a bit inefficient
-        self.mc.MOV(tmploc, loc)
-        self.mc.SHL(tmploc, loc2)
-        self.mc.SAR(tmploc, loc2)
-        if guard_op.opnum == rop.GUARD_NO_EXCEPTION:
-            self.mc.CMP(tmploc, loc)
-            self.mc.JNE(rel32(addr))
-            self.mc.SHL(loc, loc2)
-        elif guard_op.opnum == rop.GUARD_EXCEPTION:
-            # xxx even more inefficient
-            self.mc.SUB(tmploc, loc)
-            self.mc.SHL(loc, loc2)
-            self.mc.CMP(tmploc, imm8(0))
-            self.mc.JE(rel32(addr))
-        else:
-            raise AssertionError
-
     def genop_int_is_true(self, op, arglocs, resloc):
         argloc = arglocs[0]
         self.mc.TEST(argloc, argloc)

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	Wed Jun 17 18:11:26 2009
@@ -811,15 +811,6 @@
     consider_int_invert = consider_int_neg
     consider_bool_not = consider_int_neg
 
-    def consider_int_neg_ovf(self, op, guard_op):
-        res = self.force_result_in_reg(op.result, op.args[0], [])
-        self.position += 1
-        regalloc = self.regalloc_for_guard(guard_op)
-        self.perform_with_guard(op, guard_op, regalloc, [res], res,
-                                overflow=True)
-        self.eventually_free_vars(guard_op.inputargs)
-        self.eventually_free_var(guard_op.result)
-
     def consider_int_lshift(self, op, ignored):
         if isinstance(op.args[1], Const):
             loc2 = convert_to_imm(op.args[1])
@@ -832,22 +823,6 @@
     consider_int_rshift  = consider_int_lshift
     consider_uint_rshift = consider_int_lshift
 
-    def consider_int_lshift_ovf(self, op, guard_op):
-        if isinstance(op.args[1], Const):
-            loc2 = convert_to_imm(op.args[1])
-        else:
-            loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
-        tmpvar = TempBox()
-        tmploc = self.force_allocate_reg(tmpvar, [op.args[1], op.result])
-        self.eventually_free_vars(op.args)
-        self.position += 1
-        regalloc = self.regalloc_for_guard(guard_op)
-        self.perform_with_guard(op, guard_op, regalloc, [loc1, loc2, tmploc],
-                                loc1, overflow=True)
-        self.eventually_free_vars(guard_op.inputargs)
-        self.eventually_free_var(tmpvar)
-
     def _consider_int_div_or_mod(self, op, resultreg, trashreg):
         l0 = self.make_sure_var_in_reg(op.args[0], [], eax)
         l1 = self.make_sure_var_in_reg(op.args[1], [], ecx)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Wed Jun 17 18:11:26 2009
@@ -661,6 +661,37 @@
                                         self.var_position(op.args[1]))
         self.default_serialize_op(op, 'int_floordiv')
 
+    def serialize_op_int_lshift_ovf(self, op):
+        self.default_serialize_op(op, 'int_lshift')
+        renaming_list = range(0, self.free_vars*2, 2)
+        #
+        v_tmp1 = Variable()
+        v_tmp1.concretetype = lltype.Signed
+        self.emit('int_rshift', self.var_position(op.result),
+                                self.var_position(op.args[1]))
+        self.register_var(v_tmp1)
+        #
+        v_tmp2 = Variable()
+        v_tmp2.concretetype = lltype.Bool
+        self.emit('int_ne', self.var_position(v_tmp1),
+                            self.var_position(op.args[0]))
+        self.register_var(v_tmp2)
+        #
+        common_case = object()
+        self.emit("goto_if_not",
+                  tlabel(common_case),
+                  self.var_position(v_tmp2),
+                  len(renaming_list), *renaming_list)
+        #
+        self.emit("overflow_error")
+        #
+        self.emit(label(common_case))
+
+    def serialize_op_int_neg_ovf(self, op):
+        self.emit('int_sub_ovf', self.var_position(Constant(0)),
+                                 self.var_position(op.args[0]))
+        self.register_var(op.result)
+
     def serialize_op_hint(self, op):
         hints = op.args[1].value
         if hints.get('promote') and op.args[0].concretetype is not lltype.Void:

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py	Wed Jun 17 18:11:26 2009
@@ -204,27 +204,6 @@
         cpu.clear_exception()
     return BoxInt(z)
 
-def do_int_neg_ovf(cpu, args, descr=None):
-    x = args[0].getint()
-    try:
-        z = ovfcheck(-x)
-    except OverflowError:
-        cpu.set_overflow_error()
-        z = 0
-    else:
-        cpu.clear_exception()
-    return BoxInt(z)
-
-def do_int_lshift_ovf(cpu, args, descr=None):
-    x = args[0].getint()
-    y = args[1].getint()
-    try:
-        z = ovfcheck(x << y)
-    except OverflowError:
-        cpu.set_overflow_error()
-        z = 0
-    return BoxInt(z)
-
 # ____________________________________________________________
 
 

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Wed Jun 17 18:11:26 2009
@@ -267,8 +267,7 @@
                 self.execute(rop.%s, [b1, b2])
         ''' % (_opimpl, _opimpl.upper())).compile()
 
-    for _opimpl in ['int_add_ovf', 'int_sub_ovf', 'int_mul_ovf',
-                    'int_lshift_ovf']:
+    for _opimpl in ['int_add_ovf', 'int_sub_ovf', 'int_mul_ovf']:
         exec py.code.Source('''
             @arguments("box", "box")
             def opimpl_%s(self, b1, b2):
@@ -284,14 +283,6 @@
                 self.execute(rop.%s, [b])
         ''' % (_opimpl, _opimpl.upper())).compile()
 
-    for _opimpl in ['int_neg_ovf',
-                    ]:
-        exec py.code.Source('''
-            @arguments("box")
-            def opimpl_%s(self, b):
-                return self.execute_with_exc(rop.%s, [b])
-        ''' % (_opimpl, _opimpl.upper())).compile()
-
     @arguments()
     def opimpl_return(self):
         assert len(self.env) == 1
@@ -321,11 +312,15 @@
         # typically not included in the livelist.
 
     def follow_jump(self):
+        _op_goto_if_not = self.metainterp.staticdata._op_goto_if_not
+        assert ord(self.bytecode[self.pc]) == _op_goto_if_not
         self.pc += 1          # past the bytecode for 'goto_if_not'
         target = self.load_3byte()  # load the 'target' argument
         self.pc = target      # jump
 
     def dont_follow_jump(self):
+        _op_goto_if_not = self.metainterp.staticdata._op_goto_if_not
+        assert ord(self.bytecode[self.pc]) == _op_goto_if_not
         self.pc += 1          # past the bytecode for 'goto_if_not'
         self.load_3byte()     # past the 'target' argument
         self.load_int()       # past the 'box' argument
@@ -397,6 +392,7 @@
     def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
         negbox = self.metainterp.execute_and_record(
             rop.INT_LT, [indexbox, ConstInt(0)])
+        # XXXXXXXXXXXXXXXXXXXXX fix me
         negbox = self.implement_guard_value(pc, negbox)
         if negbox.getint():
             # the index is < 0; add the array length to it
@@ -410,6 +406,7 @@
     def opimpl_check_zerodivisionerror(self, pc, box):
         nonzerobox = self.metainterp.execute_and_record(
             rop.INT_NE, [box, ConstInt(0)])
+        # XXXXXXXXXXXXXXXXXXXXX fix me
         nonzerobox = self.implement_guard_value(pc, nonzerobox)
         if nonzerobox.getint():
             return False
@@ -428,6 +425,7 @@
             rop.INT_AND, [tmp1, box2])                    # tmp2=-1
         tmp3 = self.metainterp.execute_and_record(
             rop.INT_EQ, [tmp2, ConstInt(-1)])             # tmp3?
+        # XXXXXXXXXXXXXXXXXXXXX fix me
         tmp4 = self.implement_guard_value(pc, tmp3)       # tmp4?
         if not tmp4.getint():
             return False
@@ -436,10 +434,25 @@
             self.metainterp.cpu.set_overflow_error()
             return self.metainterp.handle_exception()
 
+    @arguments()
+    def opimpl_overflow_error(self):
+        # xxx indirect
+        cpu = self.metainterp.cpu
+        cpu.set_overflow_error()
+        etype = cpu.get_exception()
+        evalue = cpu.get_exc_value()
+        cpu.clear_exception()
+        #
+        ts = self.metainterp.staticdata.ts
+        return self.metainterp.finishframe_exception(
+            ts.get_exception_box(etype),
+            ts.get_exc_value_box(evalue))
+
     @arguments("orgpc", "box")
     def opimpl_int_abs(self, pc, box):
         nonneg = self.metainterp.execute_and_record(
             rop.INT_GE, [box, ConstInt(0)])
+        # XXXXXXXXXXXXXXXXXXXXX fix me
         nonneg = self.implement_guard_value(pc, nonneg)
         if nonneg.getint():
             self.make_result_box(box)
@@ -896,6 +909,8 @@
         else:
             self.profiler = EmptyProfiler()
 
+        self._op_goto_if_not = self.find_opcode('goto_if_not')
+
     def _freeze_(self):
         return True
 

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py	Wed Jun 17 18:11:26 2009
@@ -197,8 +197,6 @@
     INT_ADD_OVF            = 152
     INT_SUB_OVF            = 153
     INT_MUL_OVF            = 154
-    INT_NEG_OVF            = 155     # can only overflow in: -(-sys.maxint-1)
-    INT_LSHIFT_OVF         = 157
     _OVF_LAST = 160
     _CANRAISE_LAST = 160 # ----- end of can_raise operations -----
     _LAST = 160     # for the backend to add more internal operations

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_exception.py	Wed Jun 17 18:11:26 2009
@@ -419,6 +419,28 @@
         res = self.meta_interp(f, [809644098, 16, 0], optimizer=Optimizer)
         assert res == f(809644098, 16, 0)
 
+    def test_int_neg_ovf(self):
+        import sys
+        from pypy.jit.metainterp.simple_optimize import Optimizer
+        
+        myjitdriver = JitDriver(greens = [], reds = ['n', 'y', 'm'])
+        def f(y, n):
+            m = 0
+            while n < 115:
+                myjitdriver.can_enter_jit(n=n, y=y, m=m)
+                myjitdriver.jit_merge_point(n=n, y=y, m=m)
+                y -= 1
+                try:
+                    ovfcheck(-y)
+                except OverflowError:
+                    m += 1
+                    y += 1
+                n += 1
+            return m
+
+        res = self.meta_interp(f, [-sys.maxint-1+100, 0], optimizer=Optimizer)
+        assert res == 16
+
     def test_reraise_through_portal(self):
         jitdriver = JitDriver(greens = [], reds = ['n'])
 



More information about the Pypy-commit mailing list