def _optimize_CALL_INT_PY_DIV(self, op): arg1 = op.getarg(1) b1 = self.getintbound(arg1) arg2 = op.getarg(2) b2 = self.getintbound(arg2) if b1.equal(0): self.make_constant_int(op, 0) self.last_emitted_operation = REMOVED return True if not b2.is_constant(): return False val = b2.getint() if val <= 0: return False if val == 1: self.make_equal_to(op, arg1) self.last_emitted_operation = REMOVED return True elif val & (val - 1) == 0: # val == 2**shift from rpython.jit.metainterp.history import DONT_CHANGE op = self.replace_op_with(op, rop.INT_RSHIFT, args=[arg1, ConstInt(highest_bit(val))], descr=DONT_CHANGE) # <- xxx rename? means "kill" self.optimizer.send_extra_operation(op) return True else: from rpython.jit.metainterp.optimizeopt import intdiv known_nonneg = b1.known_nonnegative() operations = intdiv.division_operations(arg1, val, known_nonneg) newop = None for newop in operations: self.optimizer.send_extra_operation(newop) self.make_equal_to(op, newop) return True
def test_division_operations(n, m, known_nonneg): if n < 0: known_nonneg = False n_box = InputArgInt() ops = division_operations(n_box, m, known_nonneg) constants = {n_box: ConstInt(n)} for op in ops: argboxes = op.getarglist() constantboxes = [constants.get(box, box) for box in argboxes] res = execute(None, None, op.getopnum(), None, *constantboxes) constants[op] = ConstInt(res) assert constants[op].getint() == n // m
def _optimize_CALL_INT_PY_DIV(self, op): arg1 = op.getarg(1) b1 = self.getintbound(arg1) arg2 = op.getarg(2) b2 = self.getintbound(arg2) if b1.is_constant() and b1.getint() == 0: self.make_constant_int(op, 0) self.last_emitted_operation = REMOVED return True # This is Python's integer division: 'x // (2**shift)' can always # be replaced with 'x >> shift', even for negative values of x if not b2.is_constant(): return False val = b2.getint() if val <= 0: return False if val == 1: self.make_equal_to(op, arg1) self.last_emitted_operation = REMOVED return True elif val & (val - 1) == 0: # val == 2**shift from rpython.jit.metainterp.history import DONT_CHANGE op = self.replace_op_with( op, rop.INT_RSHIFT, args=[arg1, ConstInt(highest_bit(val))], descr=DONT_CHANGE ) # <- xxx rename? means "kill" self.optimizer.send_extra_operation(op) return True else: from rpython.jit.metainterp.optimizeopt import intdiv known_nonneg = b1.known_ge(IntBound(0, 0)) operations = intdiv.division_operations(arg1, val, known_nonneg) newop = None for newop in operations: self.optimizer.send_extra_operation(newop) self.make_equal_to(op, newop) return True