Exemple #1
0
    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
Exemple #3
0
    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