Example #1
0
 def optimize_INT_MOD(self, op):
     v1 = self.getvalue(op.getarg(0))
     v2 = self.getvalue(op.getarg(1))
     known_nonneg = (v1.getintbound().known_ge(IntBound(0, 0)) and
                     v2.getintbound().known_ge(IntBound(0, 0)))
     if known_nonneg and v2.is_constant():
         val = v2.box.getint()
         if (val & (val-1)) == 0:
             # nonneg % power-of-two ==> nonneg & (power-of-two - 1)
             arg1 = op.getarg(0)
             arg2 = ConstInt(val-1)
             op = op.copy_and_change(rop.INT_AND, args=[arg1, arg2])
     self.emit_operation(op)
     if v2.is_constant():
         val = v2.box.getint()
         r = self.getvalue(op.result)
         if val < 0:
             if val == -sys.maxint-1:
                 return     # give up
             val = -val
         if known_nonneg:
             r.getintbound().make_ge(IntBound(0, 0))
         else:
             r.getintbound().make_gt(IntBound(-val, -val))
         r.getintbound().make_lt(IntBound(val, val))
Example #2
0
 def make_constant(self, constbox):
     """Replace 'self.box' with a Const box."""
     assert isinstance(constbox, ConstInt)
     self.box = constbox
     self.setlevel(LEVEL_CONSTANT)
     val = constbox.getint()
     self.intbound = IntBound(val, val)
Example #3
0
 def optimize_INT_MOD(self, op):
     b1 = self.getintbound(op.getarg(0))
     b2 = self.getintbound(op.getarg(1))
     known_nonneg = (b1.known_ge(IntBound(0, 0))
                     and b2.known_ge(IntBound(0, 0)))
     if known_nonneg and b2.is_constant():
         val = b2.getint()
         if (val & (val - 1)) == 0:
             # nonneg % power-of-two ==> nonneg & (power-of-two - 1)
             arg1 = op.getarg(0)
             arg2 = ConstInt(val - 1)
             op = self.replace_op_with(op, rop.INT_AND, args=[arg1, arg2])
     self.emit_operation(op)
     if b2.is_constant():
         val = b2.getint()
         r = self.getintbound(op)
         if val < 0:
             if val == -sys.maxint - 1:
                 return  # give up
             val = -val
         if known_nonneg:
             r.make_ge(IntBound(0, 0))
         else:
             r.make_gt(IntBound(-val, -val))
         r.make_lt(IntBound(val, val))
Example #4
0
 def propagate_bounds_INT_IS_TRUE(self, op):
     r = self.getvalue(op.result)
     if r.is_constant():
         if r.box.same_constant(CONST_1):
             v1 = self.getvalue(op.getarg(0))
             if v1.getintbound().known_ge(IntBound(0, 0)):
                 v1.getintbound().make_gt(IntBound(0, 0))
                 self.propagate_bounds_backward(op.getarg(0))
Example #5
0
 def is_nonnull(self):
     if OptValue.is_nonnull(self):
         return True
     if self.intbound:
         if self.intbound.known_gt(IntBound(0, 0)) or \
            self.intbound.known_lt(IntBound(0, 0)):
             return True
     return False
Example #6
0
 def postprocess_INT_OR_or_XOR(self, op):
     v1 = self.get_box_replacement(op.getarg(0))
     b1 = self.getintbound(v1)
     v2 = self.get_box_replacement(op.getarg(1))
     b2 = self.getintbound(v2)
     if b1.known_ge(IntBound(0, 0)) and \
        b2.known_ge(IntBound(0, 0)):
         r = self.getintbound(op)
         mostsignificant = b1.upper | b2.upper
         r.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
Example #7
0
 def optimize_INT_SIGNEXT(self, op):
     b = self.getintbound(op.getarg(0))
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     if bounds.contains_bound(b):
         self.make_equal_to(op, op.getarg(0))
     else:
         return self.emit(op)
Example #8
0
 def optimize_INT_SIGNEXT(self, op):
     b = self.getintbound(op.getarg(0))
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     if bounds.contains_bound(b):
         self.make_equal_to(op, op.getarg(0))
     else:
         return self.emit(op)
Example #9
0
 def propagate_bounds_INT_IS_ZERO(self, op):
     r = self.getvalue(op.result)
     if r.is_constant():
         if r.box.same_constant(CONST_1):
             v1 = self.getvalue(op.getarg(0))
             # Clever hack, we can't use self.make_constant_int yet because
             # the args aren't in the values dictionary yet so it runs into
             # an assert, this is a clever way of expressing the same thing.
             v1.getintbound().make_ge(IntBound(0, 0))
             v1.getintbound().make_lt(IntBound(1, 1))
             self.propagate_bounds_backward(op.getarg(0))
Example #10
0
 def post_call_INT_PY_MOD(self, op):
     b2 = self.getintbound(op.getarg(2))
     if b2.is_constant():
         val = b2.getint()
         r = self.getintbound(op)
         if val >= 0:  # with Python's modulo:  0 <= (x % pos) < pos
             r.make_ge(IntBound(0, 0))
             r.make_lt(IntBound(val, val))
         else:  # with Python's modulo:  neg < (x % neg) <= 0
             r.make_gt(IntBound(val, val))
             r.make_le(IntBound(0, 0))
Example #11
0
 def __init__(self, box, level=None, known_class=None, intbound=None):
     OptValue.__init__(self, box, level, None, None)
     if isinstance(box, Const):
         value = box.getint()
         self.intbound = IntBound(value, value)
         return
     if intbound:
         self.intbound = intbound
     else:
         assert isinstance(box, BoxInt)
         self.intbound = IntBound(MININT, MAXINT)
Example #12
0
 def __init__(self, box, level=None, known_class=None, intbound=None):
     OptValue.__init__(self, box, level, None, None)
     if isinstance(box, Const):
         return
     if intbound:
         self.intbound = intbound
     else:
         if isinstance(box, BoxInt):
             self.intbound = IntBound(MININT, MAXINT)
         else:
             self.intbound = IntUnbounded()
Example #13
0
 def __init__(self, box, level=None, known_class=None, intbound=None):
     OptValue.__init__(self, box, level, None, None)
     if isinstance(box, Const):
         return
     if intbound:
         self.intbound = intbound
     else:
         if isinstance(box, BoxInt):
             self.intbound = IntBound(MININT, MAXINT)
         else:
             self.intbound = IntUnbounded()
Example #14
0
 def __init__(self, box, level=None, known_class=None, intbound=None):
     OptValue.__init__(self, box, level, None, None)
     if isinstance(box, Const):
         value = box.getint()
         self.intbound = IntBound(value, value)
         return
     if intbound:
         self.intbound = intbound
     else:
         assert isinstance(box, BoxInt)
         self.intbound = IntBound(MININT, MAXINT)
Example #15
0
 def optimize_INT_SIGNEXT(self, op):
     value = self.getvalue(op.getarg(0))
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     if bounds.contains_bound(value.getintbound()):
         self.make_equal_to(op.result, value)
     else:
         self.emit_operation(op)
         vres = self.getvalue(op.result)
         vres.getintbound().intersect(bounds)
Example #16
0
 def optimize_INT_SIGNEXT(self, op):
     b = self.getintbound(op.getarg(0))
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     if bounds.contains_bound(b):
         self.make_equal_to(op, op.getarg(0))
     else:
         self.emit_operation(op)
         bres = self.getintbound(op)
         bres.intersect(bounds)
Example #17
0
 def optimize_INT_SIGNEXT(self, op):
     b = self.getintbound(op.getarg(0))
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     if bounds.contains_bound(b):
         self.make_equal_to(op, op.getarg(0))
     else:
         self.emit_operation(op)
         bres = self.getintbound(op)
         bres.intersect(bounds)
Example #18
0
 def postprocess_INT_AND(self, op):
     b1 = self.getintbound(op.getarg(0))
     b2 = self.getintbound(op.getarg(1))
     r = self.getintbound(op)
     pos1 = b1.known_ge(IntBound(0, 0))
     pos2 = b2.known_ge(IntBound(0, 0))
     if pos1 or pos2:
         r.make_ge(IntBound(0, 0))
     if pos1:
         r.make_le(b1)
     if pos2:
         r.make_le(b2)
Example #19
0
def test_shift_overflow():
    b10 = IntBound(0, 10)
    b100 = IntBound(0, 100)
    bmax = IntBound(0, sys.maxint/2)
    assert not b10.lshift_bound(b100).has_upper
    assert not bmax.lshift_bound(b10).has_upper
    assert b10.lshift_bound(b10).has_upper

    for b in (b10, b100, bmax, IntBound(0, 0)):
        for shift_count_bound in (IntBound(7, LONG_BIT), IntBound(-7, 7)):
            #assert not b.lshift_bound(shift_count_bound).has_upper
            assert not b.rshift_bound(shift_count_bound).has_upper
 def _propagate_int_is_true_or_zero(self, op, constnonzero, constzero):
     r = self.getvalue(op.result)
     if r.is_constant():
         if r.box.same_constant(constnonzero):
             v1 = self.getvalue(op.getarg(0))
             if v1.getintbound().known_ge(IntBound(0, 0)):
                 v1.getintbound().make_gt(IntBound(0, 0))
                 self.propagate_bounds_backward(op.getarg(0))
         elif r.box.same_constant(constzero):
             v1 = self.getvalue(op.getarg(0))
             # Clever hack, we can't use self.make_constant_int yet because
             # the args aren't in the values dictionary yet so it runs into
             # an assert, this is a clever way of expressing the same thing.
             v1.getintbound().make_ge(IntBound(0, 0))
             v1.getintbound().make_lt(IntBound(1, 1))
             self.propagate_bounds_backward(op.getarg(0))
Example #21
0
 def postprocess_INT_SIGNEXT(self, op):
     numbits = op.getarg(1).getint() * 8
     start = -(1 << (numbits - 1))
     stop = 1 << (numbits - 1)
     bounds = IntBound(start, stop - 1)
     bres = self.getintbound(op)
     bres.intersect(bounds)
Example #22
0
 def test_intbounds(self):
     value1 = OptValue(BoxInt())
     value1.intbound.make_ge(IntBound(0, 10))
     value1.intbound.make_le(IntBound(20, 30))
     info1 = NotVirtualStateInfo(value1)
     info2 = NotVirtualStateInfo(OptValue(BoxInt()))
     expected = """
     [i0]
     i1 = int_ge(i0, 0)
     guard_true(i1) []
     i2 = int_le(i0, 30)
     guard_true(i2) []
     """
     self.guards(info1, info2, BoxInt(15), expected)
     py.test.raises(InvalidLoop, self.guards,
                    info1, info2, BoxInt(50), expected)
Example #23
0
 def make_constant(self, constbox):
     """Replace 'self.box' with a Const box."""
     assert isinstance(constbox, ConstInt)
     self.box = constbox
     self.setlevel(LEVEL_CONSTANT)
     val = constbox.getint()
     self.intbound = IntBound(val, val)
Example #24
0
 def optimize_INT_OR_or_XOR(self, op):
     v1 = self.getvalue(op.getarg(0))
     v2 = self.getvalue(op.getarg(1))
     if v1 is v2:
         if op.getopnum() == rop.INT_OR:
             self.make_equal_to(op.result, v1)
         else:
             self.make_constant_int(op.result, 0)
         return
     self.emit_operation(op)
     bound1 = v1.getintbound()
     bound2 = v2.getintbound()
     if bound1.known_ge(IntBound(0, 0)) and \
        bound2.known_ge(IntBound(0, 0)):
         r = self.getvalue(op.result).getintbound()
         mostsignificant = bound1.upper | bound2.upper
         r.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
Example #25
0
    def optimize_INT_AND(self, op):
        b1 = self.getintbound(op.getarg(0))
        b2 = self.getintbound(op.getarg(1))
        self.emit_operation(op)

        r = self.getintbound(op)
        if b2.is_constant():
            val = b2.lower
            if val >= 0:
                r.intersect(IntBound(0, val))
        elif b1.is_constant():
            val = b1.lower
            if val >= 0:
                r.intersect(IntBound(0, val))
        elif b1.known_ge(IntBound(0, 0)) and b2.known_ge(IntBound(0, 0)):
            lesser = min(b1.upper, b2.upper)
            r.intersect(IntBound(0, next_pow2_m1(lesser)))
Example #26
0
 def optimize_INT_OR_or_XOR(self, op):
     v1 = self.get_box_replacement(op.getarg(0))
     b1 = self.getintbound(v1)
     v2 = self.get_box_replacement(op.getarg(1))
     b2 = self.getintbound(v2)
     if v1 is v2:
         if op.getopnum() == rop.INT_OR:
             self.make_equal_to(op, v1)
         else:
             self.make_constant_int(op, 0)
         return
     self.emit_operation(op)
     if b1.known_ge(IntBound(0, 0)) and \
        b2.known_ge(IntBound(0, 0)):
         r = self.getintbound(op)
         mostsignificant = b1.upper | b2.upper
         r.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
Example #27
0
def bound(a, b):
    if a is None and b is None:
        return IntUnbounded()
    elif a is None:
        return IntUpperBound(b)
    elif b is None:
        return IntLowerBound(a)
    else:
        return IntBound(a, b)
Example #28
0
    def optimize_INT_AND(self, op):
        v1 = self.getvalue(op.getarg(0))
        v2 = self.getvalue(op.getarg(1))
        self.emit_operation(op)

        r = self.getvalue(op.result)
        if v2.is_constant():
            val = v2.box.getint()
            if val >= 0:
                r.getintbound().intersect(IntBound(0, val))
        elif v1.is_constant():
            val = v1.box.getint()
            if val >= 0:
                r.getintbound().intersect(IntBound(0, val))
        elif v1.getintbound().known_ge(IntBound(0, 0)) and \
          v2.getintbound().known_ge(IntBound(0, 0)):
            lesser = min(v1.getintbound().upper, v2.getintbound().upper)
            r.getintbound().intersect(IntBound(0, next_pow2_m1(lesser)))
Example #29
0
 def _propagate_int_is_true_or_zero(self, op, valnonzero, valzero):
     if self.is_raw_ptr(op.getarg(0)):
         return
     r = self.getintbound(op)
     if r.is_constant():
         if r.getint() == valnonzero:
             b1 = self.getintbound(op.getarg(0))
             if b1.known_ge(IntBound(0, 0)):
                 b1.make_gt(IntBound(0, 0))
                 self.propagate_bounds_backward(op.getarg(0))
         elif r.getint() == valzero:
             b1 = self.getintbound(op.getarg(0))
             # XXX remove this hack maybe?
             # Clever hack, we can't use self.make_constant_int yet because
             # the args aren't in the values dictionary yet so it runs into
             # an assert, this is a clever way of expressing the same thing.
             b1.make_ge(IntBound(0, 0))
             b1.make_lt(IntBound(1, 1))
             self.propagate_bounds_backward(op.getarg(0))
Example #30
0
 def make_len_gt(self, mode, descr, val):
     if self.lenbound:
         if self.lenbound.mode != mode or self.lenbound.descr != descr:
             # XXX a rare case?  it seems to occur sometimes when
             # running lib-python's test_io.py in PyPy on Linux 32...
             from rpython.jit.metainterp.optimize import InvalidLoop
             raise InvalidLoop("bad mode/descr")
         self.lenbound.bound.make_gt(IntBound(val, val))
     else:
         self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1))
Example #31
0
 def _optimize_CALL_DICT_LOOKUP(self, op):
     # Cache consecutive lookup() calls on the same dict and key,
     # depending on the 'flag_store' argument passed:
     # FLAG_LOOKUP: always cache and use the cached result.
     # FLAG_STORE:  don't cache (it might return -1, which would be
     #                incorrect for future lookups); but if found in
     #                the cache and the cached value was already checked
     #                non-negative, then we can reuse it.
     # FLAG_DELETE: never cache, never use the cached result (because
     #                if there is a cached result, the FLAG_DELETE call
     #                is needed for its side-effect of removing it).
     #                In theory we could cache a -1 for the case where
     #                the delete is immediately followed by a lookup,
     #                but too obscure.
     #
     from rpython.rtyper.lltypesystem.rordereddict import FLAG_LOOKUP
     from rpython.rtyper.lltypesystem.rordereddict import FLAG_STORE
     flag_value = self.getintbound(op.getarg(4))
     if not flag_value.is_constant():
         return False
     flag = flag_value.getint()
     if flag != FLAG_LOOKUP and flag != FLAG_STORE:
         return False
     #
     descrs = op.getdescr().get_extra_info().extradescrs
     assert descrs  # translation hint
     descr1 = descrs[0]
     try:
         d = self.cached_dict_reads[descr1]
     except KeyError:
         d = self.cached_dict_reads[descr1] = args_dict()
         self.corresponding_array_descrs[descrs[1]] = descr1
     #
     key = [
         get_box_replacement(op.getarg(1)),  # dict
         get_box_replacement(op.getarg(2))
     ]  # key
     # other args can be ignored here (hash, store_flag)
     try:
         res_v = d[key]
     except KeyError:
         if flag == FLAG_LOOKUP:
             d[key] = op
         return False
     else:
         if flag != FLAG_LOOKUP:
             if not self.getintbound(res_v).known_ge(IntBound(0, 0)):
                 return False
         self.make_equal_to(op, res_v)
         self.last_emitted_operation = REMOVED
         return True
Example #32
0
 def getintbound(self, op):
     assert op.type == 'i'
     op = get_box_replacement(op)
     if isinstance(op, ConstInt):
         return ConstIntBound(op.getint())
     fw = op.get_forwarded()
     if fw is not None:
         if isinstance(fw, IntBound):
             return fw
         # rare case: fw might be a RawBufferPtrInfo
         return IntUnbounded()
     assert op.type == 'i'
     intbound = IntBound(MININT, MAXINT)
     op.set_forwarded(intbound)
     return intbound
Example #33
0
    def optimize_INT_FLOORDIV(self, op):
        v1 = self.getvalue(op.getarg(0))
        v2 = self.getvalue(op.getarg(1))

        if v2.is_constant() and v2.box.getint() == 1:
            self.make_equal_to(op.result, v1)
            return
        elif v1.is_constant() and v1.box.getint() == 0:
            self.make_constant_int(op.result, 0)
            return
        if v1.getintbound().known_ge(IntBound(0, 0)) and v2.is_constant():
            val = v2.box.getint()
            if val & (val - 1) == 0 and val > 0:  # val == 2**shift
                op = op.copy_and_change(
                    rop.INT_RSHIFT,
                    args=[op.getarg(0),
                          ConstInt(highest_bit(val))])
        self.emit_operation(op)
Example #34
0
    def _optimize_CALL_INT_PY_MOD(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_constant_int(op, 0)
            self.last_emitted_operation = REMOVED
            return True
        elif val & (val - 1) == 0:  # val == 2**shift
            from rpython.jit.metainterp.history import DONT_CHANGE
            # x % power-of-two ==> x & (power-of-two - 1)
            # with Python's modulo, this is valid even if 'x' is negative.
            op = self.replace_op_with(
                op,
                rop.INT_AND,
                args=[arg1, ConstInt(val - 1)],
                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.modulo_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
Example #35
0
    def optimize_INT_FLOORDIV(self, op):
        arg0 = op.getarg(0)
        b1 = self.getintbound(arg0)
        arg1 = op.getarg(1)
        b2 = self.getintbound(arg1)

        if b2.is_constant() and b2.getint() == 1:
            self.make_equal_to(op, arg0)
            return
        elif b1.is_constant() and b1.getint() == 0:
            self.make_constant_int(op, 0)
            return
        if b1.known_ge(IntBound(0, 0)) and b2.is_constant():
            val = b2.getint()
            if val & (val - 1) == 0 and val > 0:  # val == 2**shift
                op = self.replace_op_with(
                    op,
                    rop.INT_RSHIFT,
                    args=[op.getarg(0),
                          ConstInt(highest_bit(val))])
        self.emit_operation(op)
Example #36
0
    def test_NotVirtualStateInfo_generalization(self):
        def isgeneral(value1, value2):
            info1 = NotVirtualStateInfo(value1)
            info1.position = 0
            info2 = NotVirtualStateInfo(value2)
            info2.position = 0
            return info1.generalization_of(info2, {}, {})

        assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7)))
        assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt()))

        ptr = OptValue(BoxPtr())
        nonnull = OptValue(BoxPtr())
        nonnull.make_nonnull(0)
        knownclass = OptValue(BoxPtr())
        knownclass.make_constant_class(ConstPtr(self.someptr1), 0)
        const = OptValue(BoxPtr)
        const.make_constant_class(ConstPtr(self.someptr1), 0)
        const.make_constant(ConstPtr(self.someptr1))
        inorder = [ptr, nonnull, knownclass, const]
        for i in range(len(inorder)):
            for j in range(i, len(inorder)):
                assert isgeneral(inorder[i], inorder[j])
                if i != j:
                    assert not isgeneral(inorder[j], inorder[i])

        value1 = OptValue(BoxInt())
        value2 = OptValue(BoxInt())
        value2.intbound.make_lt(IntBound(10, 10))
        assert isgeneral(value1, value2)
        assert not isgeneral(value2, value1)

        assert isgeneral(OptValue(ConstInt(7)), OptValue(ConstInt(7)))
        S = lltype.GcStruct('S')
        foo = lltype.malloc(S)
        fooref = lltype.cast_opaque_ptr(llmemory.GCREF, foo)
        assert isgeneral(OptValue(ConstPtr(fooref)),
                         OptValue(ConstPtr(fooref)))
Example #37
0
class IntOptValue(OptValue):
    _attrs_ = ('intbound',)

    intbound = ImmutableIntUnbounded()

    def __init__(self, box, level=None, known_class=None, intbound=None):
        OptValue.__init__(self, box, level, None, None)
        if isinstance(box, Const):
            return
        if intbound:
            self.intbound = intbound
        else:
            if isinstance(box, BoxInt):
                self.intbound = IntBound(MININT, MAXINT)
            else:
                self.intbound = IntUnbounded()

    def copy_from(self, other_value):
        assert isinstance(other_value, IntOptValue)
        self.box = other_value.box
        self.intbound = other_value.intbound
        self._tag = other_value._tag

    def make_constant(self, constbox):
        """Replace 'self.box' with a Const box."""
        assert isinstance(constbox, ConstInt)
        self.box = constbox
        self.setlevel(LEVEL_CONSTANT)
        val = constbox.getint()
        self.intbound = IntBound(val, val)

    def is_nonnull(self):
        if OptValue.is_nonnull(self):
            return True
        if self.intbound:
            if self.intbound.known_gt(IntBound(0, 0)) or \
               self.intbound.known_lt(IntBound(0, 0)):
                return True
        return False

    def make_nonnull(self, optimizer):
        assert self.getlevel() < LEVEL_NONNULL
        self.setlevel(LEVEL_NONNULL)

    def import_from(self, other, optimizer):
        OptValue.import_from(self, other, optimizer)
        if self.getlevel() != LEVEL_CONSTANT:
            if other.getintbound() is not None: # VRawBufferValue
                self.intbound.intersect(other.getintbound())

    def make_guards(self, box):
        guards = []
        level = self.getlevel()
        if level == LEVEL_CONSTANT:
            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
            guards.append(op)
        elif level == LEVEL_KNOWNCLASS:
            op = ResOperation(rop.GUARD_NONNULL, [box], None)
            guards.append(op)
        else:
            if level == LEVEL_NONNULL:
                op = ResOperation(rop.GUARD_NONNULL, [box], None)
                guards.append(op)
            self.intbound.make_guards(box, guards)
        return guards

    def getintbound(self):
        return self.intbound

    def get_last_guard(self, optimizer):
        return None

    def get_known_class(self):
        return None

    def getlenbound(self):
        return None