Commits

David Schneider committed ae8e7dd

Merge ovf ops with the following guard

Comments (0)

Files changed (3)

pypy/jit/backend/arm/assembler.py

             self._insert_checks()
 
     def can_merge_with_next_guard(self, op, i, operations):
-        if op.getopnum() == rop.CALL_MAY_FORCE or op.getopnum() == rop.CALL_ASSEMBLER:
+        num = op.getopnum()
+        if num == rop.CALL_MAY_FORCE or num == rop.CALL_ASSEMBLER:
             assert operations[i + 1].getopnum() == rop.GUARD_NOT_FORCED
             return True
-        if op.getopnum() == rop.INT_MUL_OVF:
+        if num == rop.INT_MUL_OVF or num == rop.INT_ADD_OVF or num == rop.INT_SUB_OVF:
             opnum = operations[i + 1].getopnum()
             assert opnum  == rop.GUARD_OVERFLOW or opnum == rop.GUARD_NO_OVERFLOW
             return True

pypy/jit/backend/arm/opassembler.py

 
     _mixin_ = True
 
-    def emit_op_int_add(self, op, arglocs, regalloc, fcond):
+    def emit_op_int_add(self, op, arglocs, regalloc, fcond, flags=False):
         l0, l1, res = arglocs
+        if flags:
+            s = 1
+        else:
+            s = 0
         if l0.is_imm():
-            self.mc.ADD_ri(res.value, l1.value, imm=l0.value, s=1)
+            self.mc.ADD_ri(res.value, l1.value, imm=l0.value, s=s)
         elif l1.is_imm():
-            self.mc.ADD_ri(res.value, l0.value, imm=l1.value, s=1)
+            self.mc.ADD_ri(res.value, l0.value, imm=l1.value, s=s)
         else:
             self.mc.ADD_rr(res.value, l0.value, l1.value, s=1)
 
         return fcond
 
-    def emit_op_int_sub(self, op, arglocs, regalloc, fcond):
+    def emit_op_int_sub(self, op, arglocs, regalloc, fcond, flags=False):
         l0, l1, res = arglocs
+        if flags:
+            s = 1
+        else:
+            s = 0
         if l0.is_imm():
             value = l0.getint()
             assert value >= 0
             # reverse substract ftw
-            self.mc.RSB_ri(res.value, l1.value, value, s=1)
+            self.mc.RSB_ri(res.value, l1.value, value, s=s)
         elif l1.is_imm():
             value = l1.getint()
             assert value >= 0
-            self.mc.SUB_ri(res.value, l0.value, value, s=1)
+            self.mc.SUB_ri(res.value, l0.value, value, s=s)
         else:
-            self.mc.SUB_rr(res.value, l0.value, l1.value, s=1)
+            self.mc.SUB_rr(res.value, l0.value, l1.value, s=s)
 
         return fcond
 
             assert 0
         return fcond
 
+    def emit_guard_int_add_ovf(self, op, guard, arglocs, regalloc, fcond):
+        import pdb; pdb.set_trace()
+        self.emit_op_int_add(op, arglocs[0:3], regalloc, fcond, flags=True)
+        self._emit_guard_overflow(guard, arglocs[3:], fcond)
+        return fcond
+    
+    def emit_guard_int_sub_ovf(self, op, guard, arglocs, regalloc, fcond):
+        self.emit_op_int_sub(op, arglocs[0:3], regalloc, fcond, flags=True)
+        self._emit_guard_overflow(guard, arglocs[3:], fcond)
+        return fcond
+
     emit_op_int_floordiv = gen_emit_op_by_helper_call('DIV')
     emit_op_int_mod = gen_emit_op_by_helper_call('MOD')
     emit_op_uint_floordiv = gen_emit_op_by_helper_call('UDIV')
         descr._failure_recovery_code = memaddr
         return c.AL
 
+    def _emit_guard_overflow(self, guard, failargs, fcond):
+        if guard.getopnum() == rop.GUARD_OVERFLOW:
+            fcond = self._emit_guard(guard, failargs, c.VS)
+        elif guard.getopnum() == rop.GUARD_NO_OVERFLOW:
+            fcond = self._emit_guard(guard, failargs, c.VC)
+        else:
+            assert 0
+        return fcond
+
     def emit_op_guard_true(self, op, arglocs, regalloc, fcond):
         l0 = arglocs[0]
         failargs = arglocs[1:]

pypy/jit/backend/arm/regalloc.py

             boxes.append(box)
             l1, box = self._ensure_value_is_boxed(a1, [box])
             boxes.append(box)
-        self.possibly_free_vars(boxes)
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [l0, l1, res]
 
     def prepare_op_int_sub(self, op, fcond):
             boxes.append(box)
             l1, box = self._ensure_value_is_boxed(a1, boxes)
             boxes.append(box)
-        self.possibly_free_vars(boxes)
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [l0, l1, res]
 
     def prepare_op_int_mul(self, op, fcond):
         return args
 
 
+    def prepare_guard_int_add_ovf(self, op, guard, fcond):
+        import pdb; pdb.set_trace()
+        boxes = self.prepare_op_int_add(op, fcond)
+        locs = self._prepare_guard(guard, boxes)
+        self.possibly_free_vars_for_op(op)
+        self.possibly_free_vars(guard.getfailargs())
+        return locs
+
+    def prepare_guard_int_sub_ovf(self, op, guard, fcond):
+        boxes = self.prepare_op_int_sub(op, fcond)
+        locs = self._prepare_guard(guard, boxes)
+        self.possibly_free_vars_for_op(op)
+        self.possibly_free_vars(guard.getfailargs())
+        return locs
+
     prepare_op_int_floordiv = prepare_op_by_helper_call()
     prepare_op_int_mod = prepare_op_by_helper_call()
     prepare_op_uint_floordiv = prepare_op_by_helper_call()