Ejemplo n.º 1
0
def wrap_constant(value):
    if lltype.typeOf(value) == lltype.Signed:
        return ConstInt(value)
    elif isinstance(value, bool):
        return ConstInt(int(value))
    elif lltype.typeOf(value) == longlong.FLOATSTORAGE:
        return ConstFloat(value)
    elif isinstance(value, float):
        return ConstFloat(longlong.getfloatstorage(value))
    else:
        assert lltype.typeOf(value) == llmemory.GCREF
        return ConstPtr(value)
Ejemplo n.º 2
0
def test_ResumeDataLoopMemo_other():
    memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
    const = ConstFloat(longlong.getfloatstorage(-1.0))
    tagged = memo.getconst(const)
    index, tagbits = untag(tagged)
    assert tagbits == TAGCONST
    assert memo.consts[index - TAG_CONST_OFFSET] is const
Ejemplo n.º 3
0
 def callback(asm):
     c = ConstFloat(longlong.getfloatstorage(-42.5))
     loc = self.xrm.convert_to_imm(c)
     asm.mov(loc, xmm5)
     asm.regalloc_push(xmm5)
     asm.regalloc_pop(xmm0)
     asm.mc.CVTTSD2SI(eax, xmm0)
Ejemplo n.º 4
0
 def produce_into(self, builder, r):
     if r.random() < 0.4:
         UnaryOperation.produce_into(self, builder, r)
     elif r.random() < 0.75 or not builder.cpu.supports_floats:
         self.put(builder, [ConstInt(r.random_integer())])
     else:
         self.put(builder, [ConstFloat(r.random_float_storage())])
Ejemplo n.º 5
0
 def produce_into(self, builder, r):
     if not builder.floatvars:
         raise CannotProduceOperation
     k = r.random()
     if k < 0.18:
         v_first = ConstFloat(r.random_float_storage())
     else:
         v_first = r.choice(builder.floatvars)
     if k > 0.82:
         v_second = ConstFloat(r.random_float_storage())
     else:
         v_second = r.choice(builder.floatvars)
     if abs(v_first.getfloat()) > 1E100 or abs(v_second.getfloat()) > 1E100:
         raise CannotProduceOperation     # avoid infinities
     if abs(v_second.getfloat()) < 1E-100:
         raise CannotProduceOperation     # e.g. division by zero error
     self.put(builder, [v_first, v_second])
Ejemplo n.º 6
0
def constant_from_op(op):
    if op.type == 'i':
        return ConstInt(op.getint())
    elif op.type == 'r':
        return ConstPtr(op.getref_base())
    else:
        assert op.type == 'f'
        return ConstFloat(op.getfloatstorage())
Ejemplo n.º 7
0
def constbox(v):
    if v.type == INT:
        return ConstInt(getint(v))
    if v.type == FLOAT:
        return ConstFloat(getfloatstorage(v))
    if v.type == REF:
        return ConstPtr(getref_base(v))
    assert 0, v.type
Ejemplo n.º 8
0
 def produce_into(self, builder, r):
     if not builder.floatvars:
         raise CannotProduceOperation
     k = r.random()
     if k < 0.18:
         v_first = ConstFloat(r.random_float_storage())
     else:
         v_first = r.choice(builder.floatvars)
     if k > 0.82:
         v_second = ConstFloat(r.random_float_storage())
     else:
         v_second = r.choice(builder.floatvars)
     if abs(getfloat(v_first)) > 1E100 or abs(getfloat(v_second)) > 1E100:
         raise CannotProduceOperation  # avoid infinities
     if abs(getfloat(v_second)) < 1E-100:
         raise CannotProduceOperation  # e.g. division by zero error
     self.put(builder, [v_first, v_second])
Ejemplo n.º 9
0
 def get_current_constant_fieldvalue(self):
     struct = self.struct
     fielddescr = self.fielddescr
     if self.fielddescr.is_pointer_field():
         return ConstPtr(self.cpu.bh_getfield_gc_r(struct, fielddescr))
     elif self.fielddescr.is_float_field():
         return ConstFloat(self.cpu.bh_getfield_gc_f(struct, fielddescr))
     else:
         return ConstInt(self.cpu.bh_getfield_gc_i(struct, fielddescr))
Ejemplo n.º 10
0
 def accumulate_prepare(self, state):
     vec_reg_size = state.vec_reg_size
     for pack in self.packs:
         if not pack.is_accumulating():
             continue
         if pack.leftmost().is_guard():
             # guard breaks dependencies, thus it is an accumulation pack
             continue
         for i,node in enumerate(pack.operations):
             op = node.getoperation()
             state.accumulation[op] = pack
         assert isinstance(pack, AccumPack)
         datatype = pack.getdatatype()
         bytesize = pack.getbytesize()
         count = vec_reg_size // bytesize
         signed = datatype == 'i'
         oplist = state.invariant_oplist
         # reset the box to zeros or ones
         if pack.reduce_init() == 0:
             vecop = OpHelpers.create_vec(datatype, bytesize, signed, count)
             oplist.append(vecop)
             opnum = rop.VEC_INT_XOR
             if datatype == FLOAT:
                 # see PRECISION loss below
                 raise NotImplementedError
             vecop = VecOperation(opnum, [vecop, vecop],
                                  vecop, count)
             oplist.append(vecop)
         elif pack.reduce_init() == 1:
             # PRECISION loss, because the numbers are accumulated (associative, commutative properties must hold)
             # you can end up a small number and a huge number that is finally multiplied. giving an
             # inprecision result, thus this is disabled now
             raise NotImplementedError
             # multiply is only supported by floats
             vecop = OpHelpers.create_vec_expand(ConstFloat(1.0), bytesize,
                                                 signed, count)
             oplist.append(vecop)
         else:
             raise NotImplementedError("cannot handle %s" % pack.operator)
         # pack the scalar value
         args = [vecop, pack.getleftmostseed(), ConstInt(0), ConstInt(1)]
         vecop = OpHelpers.create_vec_pack(datatype, args, bytesize,
                                           signed, count)
         oplist.append(vecop)
         seed = pack.getleftmostseed()
         state.accumulation[seed] = pack
         # rename the variable with the box
         state.setvector_of_box(seed, 0, vecop) # prevent it from expansion
         state.renamer.start_renaming(seed, vecop)
Ejemplo n.º 11
0
 def _untag(self, tagged):
     tag, v = untag(tagged)
     if tag == TAGBOX:
         return self._get(v)
     elif tag == TAGINT:
         return ConstInt(v + SMALL_INT_START)
     elif tag == TAGCONSTPTR:
         return ConstPtr(self.trace._refs[v])
     elif tag == TAGCONSTOTHER:
         if v & 1:
             return ConstFloat(self.trace._floats[v >> 1])
         else:
             return ConstInt(self.trace._bigints[v >> 1])
     else:
         assert False
Ejemplo n.º 12
0
    def optimize_FLOAT_TRUEDIV(self, op):
        arg1 = op.getarg(0)
        arg2 = op.getarg(1)
        v2 = self.getvalue(arg2)

        # replace "x / const" by "x * (1/const)" if possible
        if v2.is_constant():
            divisor = v2.box.getfloat()
            fraction = math.frexp(divisor)[0]
            # This optimization is valid for powers of two
            # but not for zeroes, some denormals and NaN:
            if fraction == 0.5 or fraction == -0.5:
                reciprocal = 1.0 / divisor
                rfraction = math.frexp(reciprocal)[0]
                if rfraction == 0.5 or rfraction == -0.5:
                    c = ConstFloat(longlong.getfloatstorage(reciprocal))
                    op = op.copy_and_change(rop.FLOAT_MUL, args=[arg1, c])
        self.emit_operation(op)
Ejemplo n.º 13
0
    def optimize_FLOAT_TRUEDIV(self, op):
        arg1 = op.getarg(0)
        arg2 = op.getarg(1)
        v2 = get_box_replacement(arg2)

        # replace "x / const" by "x * (1/const)" if possible
        newop = op
        if v2.is_constant():
            divisor = v2.getfloat()
            fraction = math.frexp(divisor)[0]
            # This optimization is valid for powers of two
            # but not for zeroes, some denormals and NaN:
            if fraction == 0.5 or fraction == -0.5:
                reciprocal = 1.0 / divisor
                rfraction = math.frexp(reciprocal)[0]
                if rfraction == 0.5 or rfraction == -0.5:
                    c = ConstFloat(longlong.getfloatstorage(reciprocal))
                    newop = self.replace_op_with(op, rop.FLOAT_MUL,
                                                 args=[arg1, c])
        return self.emit(newop)
Ejemplo n.º 14
0
 def accumulate_prepare(self, state):
     vec_reg_size = state.vec_reg_size
     for pack in self.packs:
         if not pack.is_accumulating():
             continue
         if pack.leftmost().is_guard():
             # guard breaks dependencies, thus it is an accumulation pack
             continue
         for i,node in enumerate(pack.operations):
             op = node.getoperation()
             state.accumulation[op] = pack
         assert isinstance(pack, AccumPack)
         datatype = pack.getdatatype()
         bytesize = pack.getbytesize()
         count = vec_reg_size // bytesize
         signed = datatype == 'i'
         oplist = state.invariant_oplist
         # reset the box to zeros or ones
         if pack.reduce_init() == 0:
             vecop = OpHelpers.create_vec(datatype, bytesize, signed, count)
             oplist.append(vecop)
             vecop = VecOperation(rop.VEC_INT_XOR, [vecop, vecop],
                                  vecop, count)
             oplist.append(vecop)
         elif pack.reduce_init() == 1:
             # multiply is only supported by floats
             vecop = OpHelpers.create_vec_expand(ConstFloat(1.0), bytesize,
                                                 signed, count)
             oplist.append(vecop)
         else:
             raise NotImplementedError("cannot handle %s" % pack.operator)
         # pack the scalar value
         args = [vecop, pack.getleftmostseed(), ConstInt(0), ConstInt(1)]
         vecop = OpHelpers.create_vec_pack(datatype, args, bytesize,
                                           signed, count)
         oplist.append(vecop)
         seed = pack.getleftmostseed()
         state.accumulation[seed] = pack
         # rename the variable with the box
         state.setvector_of_box(seed, 0, vecop) # prevent it from expansion
         state.renamer.start_renaming(seed, vecop)
Ejemplo n.º 15
0
def test_wrap():
    def _is(box1, box2):
        return (box1.__class__ == box2.__class__ and
                box1.value == box2.value)
    p = lltype.malloc(lltype.GcStruct('S'))
    po = lltype.cast_opaque_ptr(llmemory.GCREF, p)
    assert _is(wrap(None, 42), BoxInt(42))
    assert _is(wrap(None, 42.5), boxfloat(42.5))
    assert _is(wrap(None, p), BoxPtr(po))
    assert _is(wrap(None, 42, in_const_box=True), ConstInt(42))
    assert _is(wrap(None, 42.5, in_const_box=True), constfloat(42.5))
    assert _is(wrap(None, p, in_const_box=True), ConstPtr(po))
    if longlong.supports_longlong:
        import sys
        from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
        value = r_longlong(-sys.maxint*17)
        assert _is(wrap(None, value), BoxFloat(value))
        assert _is(wrap(None, value, in_const_box=True), ConstFloat(value))
        value_unsigned = r_ulonglong(-sys.maxint*17)
        assert _is(wrap(None, value_unsigned), BoxFloat(value))
    sfval = r_singlefloat(42.5)
    ival = longlong.singlefloat2int(sfval)
    assert _is(wrap(None, sfval), BoxInt(ival))
    assert _is(wrap(None, sfval, in_const_box=True), ConstInt(ival))
Ejemplo n.º 16
0
def constfloat(x):
    return ConstFloat(longlong.getfloatstorage(x))
Ejemplo n.º 17
0
    def build_bridge(self):
        def exc_handling(guard_op):
            # operations need to start with correct GUARD_EXCEPTION
            if guard_op._exc_box is None:
                op = ResOperation(rop.GUARD_NO_EXCEPTION, [])
            else:
                op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box])
            op.setdescr(self.builder.getfaildescr())
            op.setfailargs([])
            return op

        if self.dont_generate_more:
            return False
        r = self.r
        guard_op = self.guard_op
        fail_args = guard_op.getfailargs()
        fail_descr = guard_op.getdescr()
        op = self.should_fail_by
        if not op.getfailargs():
            return False
        for _fail_box in fail_args:
            _fail_box.set_forwarded(None)
        # generate the branch: a sequence of operations that ends in a FINISH
        subloop = DummyLoop([])
        self.subloops.append(subloop)  # keep around for debugging
        if rop.is_guard_exception(guard_op.getopnum()):
            subloop.operations.append(exc_handling(guard_op))
        bridge_builder = self.builder.fork(self.builder.cpu, subloop,
                                           op.getfailargs()[:])
        self.generate_ops(bridge_builder, r, subloop, op.getfailargs()[:])
        # note that 'self.guard_op' now points to the guard that will fail in
        # this new bridge, while 'guard_op' still points to the guard that
        # has just failed.

        if r.random() < 0.1 and self.guard_op is None:
            # Occasionally, instead of ending in a FINISH, we end in a jump
            # to another loop.  We don't do it, however, if the new bridge's
            # execution will hit 'self.guard_op', but only if it executes
            # to the FINISH normally.  (There is no point to the extra
            # complexity, as we might get the same effect by two calls
            # to build_bridge().)

            # First make up the other loop...
            #
            # New restriction: must have the same argument count and types
            # as the original loop
            subset = []
            for box in self.loop.inputargs:
                srcbox = r.choice(fail_args)
                if srcbox.type != box.type:
                    if box.type == INT:
                        srcbox = ConstInt(r.random_integer())
                    elif box.type == FLOAT:
                        srcbox = ConstFloat(r.random_float_storage())
                    else:
                        raise AssertionError(box.type)
                subset.append(srcbox)
            #
            args = []
            for x in subset:
                if x.type == INT:
                    args.append(InputArgInt(getint(x)))
                elif x.type == FLOAT:
                    args.append(InputArgFloat(getfloatstorage(x)))
                else:
                    assert 0, x.type
            rl = RandomLoop(self.builder.cpu, self.builder.fork, r, args)
            # done
            self.should_fail_by = rl.should_fail_by
            self.expected = rl.expected
            assert len(rl.loop.inputargs) == len(args)
            # The new bridge's execution will end normally at its FINISH.
            # Just replace the FINISH with the JUMP to the new loop.
            jump_op = ResOperation(rop.JUMP,
                                   subset,
                                   descr=rl.loop._targettoken)
            subloop.operations[-1] = jump_op
            self.guard_op = rl.guard_op
            self.prebuilt_ptr_consts += rl.prebuilt_ptr_consts
            self.loop._jitcelltoken.record_jump_to(rl.loop._jitcelltoken)
            self.dont_generate_more = True
        if r.random() < .05:
            return False
        dump(subloop)
        self.builder.cpu.compile_bridge(fail_descr, fail_args,
                                        subloop.operations,
                                        self.loop._jitcelltoken)

        if self.output:
            bridge_builder.print_loop(self.output, fail_descr, fail_args)
        return True
Ejemplo n.º 18
0
 def produce_into(self, builder, r):
     if r.random() < 0.4:
         UnaryFloatOperation.produce_into(self, builder, r)
     else:
         self.put(builder, [ConstFloat(r.random_float_storage())])