Ejemplo n.º 1
0
    def transitive_imply(self, other, opt, loop):
        if self.op.getopnum() != other.op.getopnum():
            # stronger restriction, intermixing e.g. <= and < would be possible
            return None
        if self.getleftkey() is not other.getleftkey():
            return None
        if not self.rhs.is_identity():
            # stronger restriction
            return None
        # this is a valid transitive guard that eliminates the loop guard
        opnum = self.transitive_cmpop(self.cmp_op.getopnum())
        box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
        compare = ResOperation(opnum, [box_rhs, other_rhs])
        opt.emit_operation(compare)
        # guard
        descr = CompileLoopVersionDescr()
        descr.copy_all_attributes_from(self.op.getdescr())
        descr.rd_vector_info = None # do not copy the accum list
        assert isinstance(descr, AbstractFailDescr)
        guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
        guard.setfailargs(loop.label.getarglist_copy())
        opt.emit_operation(guard)

        return guard
Ejemplo n.º 2
0
 def create_op(self, opnum, args, res, descr, fail_args):
     res = ResOperation(opnum, args, descr)
     if fail_args is not None:
         res.setfailargs(fail_args)
     if self._postproces:
         self._postproces(res)
     return res
Ejemplo n.º 3
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     v_cond = builder.get_bool_var(r)
     subset = builder.subset_of_intvars(r)[:4]
     for i in range(len(subset)):
         if r.random() < 0.35:
             subset[i] = ConstInt(r.random_integer())
     #
     seen = []
     def call_me(*args):
         if len(seen) == 0:
             seen.append(args)
         else:
             assert seen[0] == args
     #
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), call_me)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [v_cond, c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 4
0
 def force_box(self, op, optforce):
     if not self.is_virtual():
         return op
     optforce.forget_numberings()
     if self.mode is mode_string:
         s = self.get_constant_string_spec(optforce, mode_string)
         if s is not None:
             c_s = get_const_ptr_for_string(s)
             optforce.get_box_replacement(op).set_forwarded(c_s)
             return c_s
     else:
         s = self.get_constant_string_spec(optforce, mode_unicode)
         if s is not None:
             c_s = get_const_ptr_for_unicode(s)
             optforce.get_box_replacement(op).set_forwarded(c_s)
             return c_s
     self._is_virtual = False
     lengthbox = self.getstrlen(op, optforce.optimizer.optstring, self.mode)
     newop = ResOperation(self.mode.NEWSTR, [lengthbox])
     if not we_are_translated():
         newop.name = 'FORCE'
     optforce.emit_operation(newop)
     newop = optforce.getlastop()
     newop.set_forwarded(self)
     op = optforce.get_box_replacement(op)
     op.set_forwarded(newop)
     optstring = optforce.optimizer.optstring
     self.initialize_forced_string(op, optstring, op, CONST_0, self.mode)
     return newop
Ejemplo n.º 5
0
 def has_pure_result(self, opnum, args, descr):
     op = ResOperation(opnum, args, None, descr)
     key = self.optimizer.make_args_key(op)
     op = self.pure_operations.get(key, None)
     if op is None:
         return False
     return op.getdescr() is descr
Ejemplo n.º 6
0
 def store_final_boxes_in_guard(self, op, pendingfields):
     assert pendingfields is not None
     descr = op.getdescr()
     assert isinstance(descr, compile.ResumeGuardDescr)
     modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
     try:
         newboxes = modifier.finish(self, pendingfields)
         if len(newboxes) > self.metainterp_sd.options.failargs_limit:
             raise resume.TagOverflow
     except resume.TagOverflow:
         raise compile.giveup()
     descr.store_final_boxes(op, newboxes)
     #
     if op.getopnum() == rop.GUARD_VALUE:
         if self.getvalue(op.getarg(0)) in self.bool_boxes:
             # Hack: turn guard_value(bool) into guard_true/guard_false.
             # This is done after the operation is emitted to let
             # store_final_boxes_in_guard set the guard_opnum field of the
             # descr to the original rop.GUARD_VALUE.
             constvalue = op.getarg(1).getint()
             if constvalue == 0:
                 opnum = rop.GUARD_FALSE
             elif constvalue == 1:
                 opnum = rop.GUARD_TRUE
             else:
                 raise AssertionError("uh?")
             newop = ResOperation(opnum, [op.getarg(0)], op.result, descr)
             newop.setfailargs(op.getfailargs())
             return newop
         else:
             # a real GUARD_VALUE.  Make it use one counter per value.
             descr.make_a_counter_per_value(op)
     return op
Ejemplo n.º 7
0
 def handle_malloc_operation(self, op):
     opnum = op.getopnum()
     if opnum == rop.NEW:
         self.handle_new_fixedsize(op.getdescr(), op)
     elif opnum == rop.NEW_WITH_VTABLE:
         classint = op.getarg(0).getint()
         descr = heaptracker.vtable2descr(self.cpu, classint)
         self.handle_new_fixedsize(descr, op)
         if self.gc_ll_descr.fielddescr_vtable is not None:
             op = ResOperation(rop.SETFIELD_GC,
                               [op.result, ConstInt(classint)], None,
                               descr=self.gc_ll_descr.fielddescr_vtable)
             self.newops.append(op)
     elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         self.handle_new_array(descr, op)
     elif opnum == rop.NEWSTR:
         self.handle_new_array(self.gc_ll_descr.str_descr, op,
                               kind=FLAG_STR)
     elif opnum == rop.NEWUNICODE:
         self.handle_new_array(self.gc_ll_descr.unicode_descr, op,
                               kind=FLAG_UNICODE)
     else:
         raise NotImplementedError(op.getopname())
Ejemplo n.º 8
0
 def next(self):
     opnum = self._next()
     if oparity[opnum] == -1:
         argnum = self._next()
     else:
         argnum = oparity[opnum]
     args = []
     for i in range(argnum):
         args.append(self._untag(self._next()))
     descr_index = -1
     if opwithdescr[opnum]:
         descr_index = self._next()
         if descr_index == 0 or rop.is_guard(opnum):
             descr = None
         else:
             if descr_index < self.all_descr_len + 1:
                 descr = self.metainterp_sd.all_descrs[descr_index - 1]
             else:
                 descr = self.trace._descrs[descr_index - self.all_descr_len - 1]
     else:
         descr = None
     res = ResOperation(opnum, args, descr=descr)
     if rop.is_guard(opnum):
         assert isinstance(res, GuardResOp)
         res.rd_resume_position = descr_index
     if res.type != 'v':
         self._cache[self._index] = res
         self._index += 1
     self._count += 1
     return res
Ejemplo n.º 9
0
 def do(self, opnum, argboxes, descr=None):
     self.fakemetainterp._got_exc = None
     op = ResOperation(opnum, argboxes, descr)
     result = _execute_arglist(self.cpu, self.fakemetainterp,
                               opnum, argboxes, descr)
     if result is not None:
         c_result = wrap_constant(result)
         op.copy_value_from(c_result)
     self.loop.operations.append(op)
     return op
Ejemplo n.º 10
0
def gen_guard_true(draw, all_ops, framestack):
    arg = get_arg(draw, all_ops, allow_const=False)
    res = ResOperation(rop.GUARD_TRUE, [arg])
    if draw(strategies.booleans()):
        s = []
        for i in range(10):
            s.append(get_arg(draw, all_ops, allow_const=False))
        boxes = list(set(s))
        framestack.append(Frame(JitCode(1), 2, boxes))
    res.framestack = framestack[:]
    return res
Ejemplo n.º 11
0
 def getstrlen(self, op, string_optimizer, mode, create_ops=True):
     if self.lgtop is not None:
         return self.lgtop
     assert not self.is_virtual()
     if not create_ops:
         return None
     lengthop = ResOperation(mode.STRLEN, [op])
     lengthop.set_forwarded(self.getlenbound(mode))
     self.lgtop = lengthop
     string_optimizer.emit_operation(lengthop)
     return lengthop
Ejemplo n.º 12
0
 def optimize_NEW_ARRAY(self, op):
     sizebox = self.get_constant_box(op.getarg(0))
     if sizebox is not None:
         # if the original 'op' did not have a ConstInt as argument,
         # build a new one with the ConstInt argument
         if not isinstance(op.getarg(0), ConstInt):
             op = ResOperation(rop.NEW_ARRAY, [sizebox], op.result,
                               descr=op.getdescr())
         self.make_varray(op.getdescr(), sizebox.getint(), op.result, op)
     else:
         self.getvalue(op.result).ensure_nonnull()
         self.emit_operation(op)
Ejemplo n.º 13
0
 def _optimize_NEWSTR(self, op, mode):
     length_box = self.get_constant_box(op.getarg(0))
     if length_box and length_box.getint() <= MAX_CONST_LEN:
         # if the original 'op' did not have a ConstInt as argument,
         # build a new one with the ConstInt argument
         if not isinstance(op.getarg(0), ConstInt):
             op = ResOperation(mode.NEWSTR, [length_box], op.result)
         vvalue = self.make_vstring_plain(op.result, op, mode)
         vvalue.setup(length_box.getint())
     else:
         self.getvalue(op.result).ensure_nonnull()
         self.emit_operation(op)
         self.pure(mode.STRLEN, [op.result], op.getarg(0))
Ejemplo n.º 14
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 15
0
 def emit_operations(self, opt):
     # create trace instructions for the index
     lhs = self.emit_varops(opt, self.lhs, self.cmp_op.getarg(0))
     rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
     opnum = self.cmp_op.getopnum()
     cmp_op = ResOperation(opnum, [lhs, rhs])
     opt.emit_operation(cmp_op)
     # emit that actual guard
     guard = ResOperation(self.op.getopnum(), [cmp_op], self.op.getdescr())
     guard.setfailargs(self.op.getfailargs()[:])
     opt.emit_operation(guard)
     self.setindex(opt.operation_position()-1)
     self.setoperation(guard)
     self.setcmp(cmp_op)
Ejemplo n.º 16
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 17
0
 def gen_initialize_tid(self, v_newgcobj, tid):
     if self.gc_ll_descr.fielddescr_tid is not None:
         # produce a SETFIELD to initialize the GC header
         op = ResOperation(rop.SETFIELD_GC,
                           [v_newgcobj, ConstInt(tid)],
                           None,
                           descr=self.gc_ll_descr.fielddescr_tid)
         self.newops.append(op)
Ejemplo n.º 18
0
 def emit_load_effective_address(self, v_gcptr, v_index, base, itemscale):
     if self.cpu.supports_load_effective_address:
         i1 = ResOperation(rop.LOAD_EFFECTIVE_ADDRESS,
                           [v_gcptr, v_index, ConstInt(base),
                            ConstInt(itemscale)])
         self.emit_op(i1)
         return i1
     else:
         if itemscale > 0:
             v_index = ResOperation(rop.INT_LSHIFT,
                                    [v_index, ConstInt(itemscale)])
             self.emit_op(v_index)
         i1b = ResOperation(rop.INT_ADD, [v_gcptr, v_index])
         self.emit_op(i1b)
         i1 = ResOperation(rop.INT_ADD, [i1b, ConstInt(base)])
         self.emit_op(i1)
         return i1
Ejemplo n.º 19
0
 def handle_str_equal_level1(self, v1, v2, resultbox, mode):
     l2box = v2.getstrlen(None, mode, None)
     if isinstance(l2box, ConstInt):
         if l2box.value == 0:
             lengthbox = v1.getstrlen(self, mode, None)
             seo = self.optimizer.send_extra_operation
             seo(ResOperation(rop.INT_EQ, [lengthbox, CONST_0], resultbox))
             return True
         if l2box.value == 1:
             l1box = v1.getstrlen(None, mode, None)
             if isinstance(l1box, ConstInt) and l1box.value == 1:
                 # comparing two single chars
                 vchar1 = self.strgetitem(v1, optimizer.CVAL_ZERO, mode)
                 vchar2 = self.strgetitem(v2, optimizer.CVAL_ZERO, mode)
                 seo = self.optimizer.send_extra_operation
                 seo(
                     ResOperation(
                         rop.INT_EQ,
                         [vchar1.force_box(self),
                          vchar2.force_box(self)], resultbox))
                 return True
             if isinstance(v1, VStringSliceValue):
                 vchar = self.strgetitem(v2, optimizer.CVAL_ZERO, mode)
                 do = EffectInfo.OS_STREQ_SLICE_CHAR
                 self.generate_modified_call(do, [
                     v1.vstr.force_box(self),
                     v1.vstart.force_box(self),
                     v1.vlength.force_box(self),
                     vchar.force_box(self)
                 ], resultbox, mode)
                 return True
     #
     if v2.is_null():
         if v1.is_nonnull():
             self.make_constant(resultbox, CONST_0)
             return True
         if v1.is_null():
             self.make_constant(resultbox, CONST_1)
             return True
         op = ResOperation(rop.PTR_EQ,
                           [v1.force_box(self), llhelper.CONST_NULL],
                           resultbox)
         self.emit_operation(op)
         return True
     #
     return False
Ejemplo n.º 20
0
 def _force_elements(self, op, optforce, descr):
     self.size = -1
     # at this point we have just written the
     # 'op = CALL_I(..., OS_RAW_MALLOC_VARSIZE_CHAR)'.
     # Emit now a CHECK_MEMORY_ERROR resop.
     check_op = ResOperation(rop.CHECK_MEMORY_ERROR, [op])
     optforce.emit_extra(check_op)
     #
     buffer = self._get_buffer()
     for i in range(len(buffer.offsets)):
         # write the value
         offset = buffer.offsets[i]
         descr = buffer.descrs[i]
         itembox = buffer.values[i]
         setfield_op = ResOperation(rop.RAW_STORE,
                           [op, ConstInt(offset), itembox], descr=descr)
         optforce.emit_extra(setfield_op)
Ejemplo n.º 21
0
 def generate_modified_call(self, oopspecindex, args, result, mode):
     oopspecindex += mode.OS_offset
     cic = self.optimizer.metainterp_sd.callinfocollection
     calldescr, func = cic.callinfo_for_oopspec(oopspecindex)
     op = ResOperation(rop.CALL, [ConstInt(func)] + args,
                       result,
                       descr=calldescr)
     self.emit_operation(op)
Ejemplo n.º 22
0
 def compare_short(self, short, expected_short):
     expected_short = self.parse(expected_short)
     remap = {}
     exp = ([ResOperation(rop.LABEL, expected_short.inputargs)] +
            expected_short.operations)
     for k, v in zip(short[0].getarglist(), expected_short.inputargs):
         remap[v] = k
     equaloplists(short, exp, remap=remap)
Ejemplo n.º 23
0
 def emit_gc_store_or_indexed(self, op, ptr_box, index_box, value_box,
                              itemsize, factor, offset):
     factor, offset, index_box = \
             self._emit_mul_if_factor_offset_not_supported(index_box,
                     factor, offset)
     #
     if index_box is None:
         args = [ptr_box, ConstInt(offset), value_box, ConstInt(itemsize)]
         newload = ResOperation(rop.GC_STORE, args)
     else:
         args = [ptr_box, index_box, value_box, ConstInt(factor),
                 ConstInt(offset), ConstInt(itemsize)]
         newload = ResOperation(rop.GC_STORE_INDEXED, args)
     if op is not None:
         self.replace_op_with(op, newload)
     else:
         self.emit_op(newload)
Ejemplo n.º 24
0
 def gen_guard(self, builder, r):
     if not builder.ptrvars:
         raise CannotProduceOperation
     box = r.choice(builder.ptrvars)[0]
     op = ResOperation(self.opnum, [box])
     passing = ((self.opnum == rop.GUARD_NONNULL and getref_base(box)) or
                (self.opnum == rop.GUARD_ISNULL and not getref_base(box)))
     return op, passing
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     if len(subset) == 0:
         RES = lltype.Void
     else:
         RES = lltype.Signed
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 26
0
 def make_guards(self, box, guards, optimizer):
     if self.is_constant():
         guards.append(ResOperation(rop.GUARD_VALUE,
                                    [box, ConstInt(self.upper)]))
         return
     if self.has_lower and self.lower > MININT:
         bound = self.lower
         op = ResOperation(rop.INT_GE, [box, ConstInt(bound)])
         guards.append(op)
         op = ResOperation(rop.GUARD_TRUE, [op])
         guards.append(op)
     if self.has_upper and self.upper < MAXINT:
         bound = self.upper
         op = ResOperation(rop.INT_LE, [box, ConstInt(bound)])
         guards.append(op)
         op = ResOperation(rop.GUARD_TRUE, [op])
         guards.append(op)
Ejemplo n.º 27
0
 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, [], None)
     else:
         op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box],
                           BoxPtr())
     op.setdescr(self.builder.getfaildescr())
     op.setfailargs([])
     return op
Ejemplo n.º 28
0
    def import_state(self, targetop, exported_state):
        if not targetop: # Trace did not start with a label
            self.inputargs = self.optimizer.loop.inputargs
            self.short = None
            self.initial_virtual_state = None
            return

        self.inputargs = targetop.getarglist()
        target_token = targetop.getdescr()
        assert isinstance(target_token, TargetToken)
        if not exported_state:
            # No state exported, construct one without virtuals
            self.short = None
            virtual_state = self.get_virtual_state(self.inputargs)
            self.initial_virtual_state = virtual_state
            return

        self.short = target_token.short_preamble[:]
        self.short_seen = {}
        self.short_boxes = exported_state.short_boxes
        self.initial_virtual_state = target_token.virtual_state

        for box in self.inputargs:
            preamble_value = exported_state.exported_values[box]
            value = self.optimizer.getvalue(box)
            value.import_from(preamble_value, self.optimizer)

        # Setup the state of the new optimizer by emiting the
        # short operations and discarding the result
        self.optimizer.emitting_dissabled = True
        for op in exported_state.inputarg_setup_ops:
            self.optimizer.send_extra_operation(op)

        seen = {}
        for op in self.short_boxes.operations():
            self.ensure_short_op_emitted(op, self.optimizer, seen)
            if op and op.result:
                preamble_value = exported_state.exported_values[op.result]
                value = self.optimizer.getvalue(op.result)
                if not value.is_virtual() and not value.is_constant():
                    imp = ValueImporter(self, preamble_value, op)
                    self.optimizer.importable_values[value] = imp
                newvalue = self.optimizer.getvalue(op.result)
                newresult = newvalue.get_key_box()
                # note that emitting here SAME_AS should not happen, but
                # in case it does, we would prefer to be suboptimal in asm
                # to a fatal RPython exception.
                if newresult is not op.result and \
                   not self.short_boxes.has_producer(newresult) and \
                   not newvalue.is_constant():
                    op = ResOperation(rop.SAME_AS, [op.result], newresult)
                    self.optimizer._newoperations.append(op)
                    #if self.optimizer.loop.logops:
                    #    debug_print('  Falling back to add extra: ' +
                    #                self.optimizer.loop.logops.repr_of_resop(op))

        self.optimizer.flush()
        self.optimizer.emitting_dissabled = False
Ejemplo n.º 29
0
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes,
                         memory_manager=None):
    """Make a LoopToken that corresponds to assembler code that just
    calls back the interpreter.  Used temporarily: a fully compiled
    version of the code may end up replacing it.
    """
    jitcell_token = make_jitcell_token(jitdriver_sd)
    nb_red_args = jitdriver_sd.num_red_args
    assert len(redargtypes) == nb_red_args
    inputargs = []
    for kind in redargtypes:
        if kind == history.INT:
            box = InputArgInt()
        elif kind == history.REF:
            box = InputArgRef()
        elif kind == history.FLOAT:
            box = InputArgFloat()
        else:
            raise AssertionError
        inputargs.append(box)
    k = jitdriver_sd.portal_runner_adr
    funcbox = history.ConstInt(heaptracker.adr2int(k))
    callargs = [funcbox] + greenboxes + inputargs
    #

    jd = jitdriver_sd
    opnum = OpHelpers.call_for_descr(jd.portal_calldescr)
    call_op = ResOperation(opnum, callargs, descr=jd.portal_calldescr)
    if call_op.type != 'v' is not None:
        finishargs = [call_op]
    else:
        finishargs = []
    #
    faildescr = jitdriver_sd.propagate_exc_descr
    operations = [
        call_op,
        ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=faildescr),
        ResOperation(rop.FINISH, finishargs, descr=jd.portal_finishtoken)
    ]
    operations[1].setfailargs([])
    operations = get_deep_immutable_oplist(operations)
    cpu.compile_loop(inputargs, operations, jitcell_token, log=False)
    if memory_manager is not None:    # for tests
        memory_manager.keep_loop_alive(jitcell_token)
    return jitcell_token
Ejemplo n.º 30
0
 def gen_write_barrier(self, v_base):
     write_barrier_descr = self.gc_ll_descr.write_barrier_descr
     args = [v_base]
     self.newops.append(
         ResOperation(rop.COND_CALL_GC_WB,
                      args,
                      None,
                      descr=write_barrier_descr))
     self.write_barrier_applied[v_base] = None
Ejemplo n.º 31
0
def _int_sub(string_optimizer, box1, box2):
    if isinstance(box2, ConstInt):
        if box2.value == 0:
            return box1
        if isinstance(box1, ConstInt):
            return ConstInt(box1.value - box2.value)
    resbox = BoxInt()
    string_optimizer.emit_operation(ResOperation(rop.INT_SUB, [box1, box2], resbox))
    return resbox
Ejemplo n.º 32
0
    def gen_malloc_nursery_varsize_frame(self, sizebox):
        """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
        """
        self.emitting_an_operation_that_can_collect()
        op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE_FRAME, [sizebox])

        self.emit_op(op)
        self.remember_write_barrier(op)
        return op
Ejemplo n.º 33
0
 def do(self, opnum, argboxes, descr=None):
     self.fakemetainterp._got_exc = None
     op = ResOperation(opnum, argboxes, descr)
     if opnum != rop.ZERO_PTR_FIELD:
         result = _execute_arglist(self.cpu, self.fakemetainterp,
                                   opnum, argboxes, descr)
         if result is not None:
             c_result = wrap_constant(result)
             op.copy_value_from(c_result)
     else:
         import ctypes
         addr = self.cpu.cast_gcref_to_int(argboxes[0].getref_base())
         offset = argboxes[1].getint()
         assert (offset % ctypes.sizeof(ctypes.c_long)) == 0
         ptr = ctypes.cast(addr, ctypes.POINTER(ctypes.c_long))
         ptr[offset / ctypes.sizeof(ctypes.c_long)] = 0
     self.loop.operations.append(op)
     return op
Ejemplo n.º 34
0
 def create_op(self, opnum, args, result, descr, fail_args):
     if opnum == ESCAPE_OP.OPNUM:
         op = ESCAPE_OP(result)
         op.initarglist(args)
         assert descr is None
         return op
     if opnum == FORCE_SPILL.OPNUM:
         op = FORCE_SPILL(result)
         op.initarglist(args)
         assert descr is None
         return op
     else:
         res = ResOperation(opnum, args, result, descr)
         if fail_args is not None:
             res.setfailargs(fail_args)
         if self._postproces:
             self._postproces(res)
         return res
Ejemplo n.º 35
0
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       descr=builder.getfaildescr())
     op.setfailargs(builder.subset_of_intvars(r))
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 36
0
 def create_op(self, opnum, args, result, descr, fail_args):
     if opnum == ESCAPE_OP.OPNUM:
         op = ESCAPE_OP(result)
         op.initarglist(args)
         assert descr is None
         return op
     if opnum == FORCE_SPILL.OPNUM:
         op = FORCE_SPILL(result)
         op.initarglist(args)
         assert descr is None
         return op
     else:
         res = ResOperation(opnum, args, result, descr)
         if fail_args is not None:
             res.setfailargs(fail_args)
         if self._postproces:
             self._postproces(res)
         return res
Ejemplo n.º 37
0
def cpu_simplify_scale(cpu, index_box, factor, offset):
    # Returns (factor, offset, index_box, [ops]) where index_box is either
    # a non-constant BoxInt or None.
    if isinstance(index_box, ConstInt):
        return 1, index_box.value * factor + offset, None, False
    else:
        if factor != 1 and factor not in cpu.load_supported_factors:
            # the factor is supported by the cpu
            # x & (x - 1) == 0 is a quick test for power of 2
            assert factor > 0
            if (factor & (factor - 1)) == 0:
                index_box = ResOperation(rop.INT_LSHIFT,
                        [index_box, ConstInt(highest_bit(factor))])
            else:
                index_box = ResOperation(rop.INT_MUL,
                        [index_box, ConstInt(factor)])
            return 1, offset, index_box, True
        return factor, offset, index_box, False
Ejemplo n.º 38
0
    def gen_malloc_nursery_varsize_frame(self, sizebox, v_result):
        """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
        """
        self.emitting_an_operation_that_can_collect()
        op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE_FRAME, [sizebox],
                          v_result)

        self.newops.append(op)
        self.write_barrier_applied[v_result] = None
Ejemplo n.º 39
0
def _int_sub(string_optimizer, box1, box2):
    if isinstance(box2, ConstInt):
        if box2.value == 0:
            return box1
        if isinstance(box1, ConstInt):
            return ConstInt(box1.value - box2.value)
    op = ResOperation(rop.INT_SUB, [box1, box2])
    string_optimizer.send_extra_operation(op)
    return op
Ejemplo n.º 40
0
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       descr=builder.getfaildescr())
     op.setfailargs(builder.subset_of_intvars(r))
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 41
0
 def get_operations(self):
     var = self.var
     tolist = []
     if self.coefficient_mul != 1:
         args = [var, ConstInt(self.coefficient_mul)]
         var = ResOperation(rop.INT_MUL, args)
         tolist.append(var)
     if self.coefficient_div != 1:
         assert 0   # should never be the case with handling
                    # of INT_PY_DIV commented out in this file...
     if self.constant > 0:
         args = [var, ConstInt(self.constant)]
         var = ResOperation(rop.INT_ADD, args)
         tolist.append(var)
     if self.constant < 0:
         args = [var, ConstInt(-self.constant)]
         var = ResOperation(rop.INT_SUB, args)
         tolist.append(var)
     return tolist
Ejemplo n.º 42
0
 def optimize_VIRTUAL_REF(self, op):
     # get some constants
     vrefinfo = self.optimizer.metainterp_sd.virtualref_info
     c_cls = vrefinfo.jit_virtual_ref_const_class
     vref_descr = vrefinfo.descr
     descr_virtual_token = vrefinfo.descr_virtual_token
     descr_forced = vrefinfo.descr_forced
     #
     # Replace the VIRTUAL_REF operation with a virtual structure of type
     # 'jit_virtual_ref'.  The jit_virtual_ref structure may be forced soon,
     # but the point is that doing so does not force the original structure.
     newop = ResOperation(rop.NEW_WITH_VTABLE, [], descr=vref_descr)
     vrefvalue = self.make_virtual(c_cls, newop, vref_descr)
     op.set_forwarded(newop)
     newop.set_forwarded(vrefvalue)
     token = ResOperation(rop.FORCE_TOKEN, [])
     vrefvalue.setfield(descr_virtual_token, newop, token)
     vrefvalue.setfield(descr_forced, newop, CONST_NULL)
     return self.emit(token)
Ejemplo n.º 43
0
def convert_old_style_to_targets(loop, jump):
    newloop = TreeLoop(loop.name)
    newloop.inputargs = loop.inputargs
    newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, descr=FakeDescr())] + \
                      loop.operations
    if not jump:
        assert newloop.operations[-1].getopnum() == rop.JUMP
        newloop.operations[-1] = newloop.operations[-1].copy_and_change(
            rop.LABEL)
    return newloop
Ejemplo n.º 44
0
    def gen_malloc_frame(self, frame_info):
        descrs = self.gc_ll_descr.getframedescrs(self.cpu)
        if self.gc_ll_descr.kind == 'boehm':
            ofs, size, sign = unpack_fielddescr(descrs.jfi_frame_depth)
            if sign:
                size = -size
            args = [ConstInt(frame_info), ConstInt(ofs), ConstInt(size)]
            size = ResOperation(rop.GC_LOAD_I, args)
            self.emit_op(size)
            frame = ResOperation(rop.NEW_ARRAY, [size],
                                 descr=descrs.arraydescr)
            self.handle_new_array(descrs.arraydescr, frame)
            return self.get_box_replacement(frame)
        else:
            # we read size in bytes here, not the length
            ofs, size, sign = unpack_fielddescr(descrs.jfi_frame_size)
            if sign:
                size = -size
            args = [ConstInt(frame_info), ConstInt(ofs), ConstInt(size)]
            size = ResOperation(rop.GC_LOAD_I, args)
            self.emit_op(size)
            frame = self.gen_malloc_nursery_varsize_frame(size)
            self.gen_initialize_tid(frame, descrs.arraydescr.tid)
            # we need to explicitely zero all the gc fields, because
            # of the unusal malloc pattern

            length = self.emit_getfield(ConstInt(frame_info),
                                        descr=descrs.jfi_frame_depth, raw=True)
            self.emit_setfield(frame, self.c_zero,
                               descr=descrs.jf_extra_stack_depth)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_savedata)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_force_descr)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_descr)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_guard_exc)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_forward)
            self.gen_initialize_len(frame, length,
                                    descrs.arraydescr.lendescr)
            return self.get_box_replacement(frame)
Ejemplo n.º 45
0
 def optimize(self,
              ops,
              bridge_ops,
              expected,
              expected_loop=None,
              inline_short_preamble=True,
              jump_values=None,
              bridge_values=None):
     loop = self.parse(ops)
     info = self.unroll_and_optimize(loop, None, jump_values=jump_values)
     jitcell_token = compile.make_jitcell_token(None)
     mid_label_descr = TargetToken(jitcell_token)
     mid_label_descr.short_preamble = info.short_preamble
     mid_label_descr.virtual_state = info.virtual_state
     start_label_descr = TargetToken(jitcell_token)
     jitcell_token.target_tokens = [mid_label_descr, start_label_descr]
     loop.operations[0].setdescr(mid_label_descr)
     loop.operations[-1].setdescr(mid_label_descr)
     info.preamble.operations[0].setdescr(start_label_descr)
     guards = [op for op in loop.operations if op.is_guard()]
     assert len(guards) == 1, "more than one guard in the loop"
     bridge = self.parse(bridge_ops)
     bridge.operations[-1].setdescr(jitcell_token)
     self.add_guard_future_condition(bridge)
     trace = oparser.convert_loop_to_trace(
         bridge, FakeMetaInterpStaticData(self.cpu))
     data = compile.BridgeCompileData(
         trace,
         self.convert_values(bridge.operations[-1].getarglist(),
                             bridge_values),
         None,
         enable_opts=self.enable_opts,
         inline_short_preamble=inline_short_preamble)
     bridge_info, ops = self._do_optimize_loop(data)
     loop.check_consistency(check_descr=False)
     info.preamble.check_consistency(check_descr=False)
     bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] +
                          ops)
     bridge.inputargs = bridge_info.inputargs
     bridge.check_consistency(check_descr=False)
     expected = self.parse(expected)
     self.assert_equal(bridge,
                       convert_old_style_to_targets(expected, jump=True))
     jump_bridge = bridge.operations[-1]
     jump_d = jump_bridge.getdescr()
     jump_args = jump_bridge.getarglist()
     if loop.operations[0].getdescr() is jump_d:
         # jump to loop
         label_args = loop.operations[0].getarglist()
     else:
         assert info.preamble.operations[0].getdescr() is jump_d
         label_args = info.preamble.operations[0].getarglist()
     assert len(jump_args) == len(label_args)
     for a, b in zip(jump_args, label_args):
         assert a.type == b.type
Ejemplo n.º 46
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(),
                       descr=builder.getfaildescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 47
0
 def _emit_mul_if_factor_offset_not_supported(self, index_box,
                                              factor, offset):
     # Returns (factor, offset, index_box) where index_box is either
     # a non-constant BoxInt or None.
     if isinstance(index_box, ConstInt):
         return 1, index_box.value * factor + offset, None
     else:
         if factor != 1 and factor not in self.cpu.load_supported_factors:
             # the factor is supported by the cpu
             # x & (x - 1) == 0 is a quick test for power of 2
             assert factor > 0
             if (factor & (factor - 1)) == 0:
                 index_box = ResOperation(rop.INT_LSHIFT,
                         [index_box, ConstInt(highest_bit(factor))])
             else:
                 index_box = ResOperation(rop.INT_MUL,
                         [index_box, ConstInt(factor)])
             self.emit_op(index_box)
             factor = 1
         return factor, offset, index_box
Ejemplo n.º 48
0
def _int_add(optstring, box1, box2):
    if isinstance(box1, ConstInt):
        if box1.value == 0:
            return box2
        if isinstance(box2, ConstInt):
            return ConstInt(box1.value + box2.value)
    elif isinstance(box2, ConstInt) and box2.value == 0:
        return box1
    op = ResOperation(rop.INT_ADD, [box1, box2])
    optstring.optimizer.send_extra_operation(op)
    return op
Ejemplo n.º 49
0
 def _force_elements(self, op, optforce, descr):
     if self._fields is None:
         return
     for i, fielddescr in enumerate(descr.get_all_fielddescrs()):
         fld = self._fields[i]
         if fld is not None:
             subbox = optforce.force_box(fld)
             setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox],
                                       descr=fielddescr)
             self._fields[i] = None
             optforce.emit_operation(setfieldop)
Ejemplo n.º 50
0
 def optimize_VIRTUAL_REF(self, op):
     # get some constants
     vrefinfo = self.optimizer.metainterp_sd.virtualref_info
     c_cls = vrefinfo.jit_virtual_ref_const_class
     vref_descr = vrefinfo.descr
     descr_virtual_token = vrefinfo.descr_virtual_token
     descr_forced = vrefinfo.descr_forced
     #
     # Replace the VIRTUAL_REF operation with a virtual structure of type
     # 'jit_virtual_ref'.  The jit_virtual_ref structure may be forced soon,
     # but the point is that doing so does not force the original structure.
     newop = ResOperation(rop.NEW_WITH_VTABLE, [], descr=vref_descr)
     vrefvalue = self.make_virtual(c_cls, newop, vref_descr)
     op.set_forwarded(newop)
     newop.set_forwarded(vrefvalue)
     token = ResOperation(rop.FORCE_TOKEN, [])
     self.emit_operation(token)
     vrefvalue.setfield(descr_virtual_token, newop, token)
     vrefvalue.setfield(descr_forced, newop,
                        self.optimizer.cpu.ts.CONST_NULLREF)
Ejemplo n.º 51
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box],
                       descr=builder.getfaildescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 52
0
 def _really_force(self, optforce):
     if self.mode is mode_string:
         s = self.get_constant_string_spec(mode_string)
         if s is not None:
             c_s = get_const_ptr_for_string(s)
             self.make_constant(c_s)
             return
     else:
         s = self.get_constant_string_spec(mode_unicode)
         if s is not None:
             c_s = get_const_ptr_for_unicode(s)
             self.make_constant(c_s)
             return
     assert self.source_op is not None
     self.box = box = self.source_op.result
     lengthbox = self.getstrlen(optforce, self.mode, None)
     op = ResOperation(self.mode.NEWSTR, [lengthbox], box)
     if not we_are_translated():
         op.name = 'FORCE'
     optforce.emit_operation(op)
     self.initialize_forced_string(optforce, box, CONST_0, self.mode)
Ejemplo n.º 53
0
 def parse_loop(self, ops, add_label=True):
     loop = self.parse(ops, postprocess=self.postprocess)
     loop.operations = filter(lambda op: op.getopnum() != rop.DEBUG_MERGE_POINT, loop.operations)
     token = JitCellToken()
     if add_label:
         label = ResOperation(rop.LABEL, loop.inputargs, descr=TargetToken(token))
     else:
         label = loop.operations[0]
         label.setdescr(TargetToken(token))
     jump = loop.operations[-1]
     loop = VectorLoop(label, loop.operations[0:-1], jump)
     loop.jump.setdescr(token)
     class Optimizer(object):
         metainterp_sd = FakeMetaInterpStaticData(self.cpu)
         jitdriver_sd = FakeJitDriverStaticData()
     opt = Optimizer()
     opt.jitdriver_sd.vec = True
     for op in loop.operations:
         if op.is_guard() and not op.getdescr():
             descr = invent_fail_descr_for_op(op.getopnum(), opt)
             op.setdescr(descr)
     return loop
Ejemplo n.º 54
0
 def test_opcount_filling_guard(self):
     descr = ArrayDescr(0,4, None, 'S')
     vec = ResOperation(rop.VEC_RAW_LOAD_I, ['a','i'], descr=descr)
     vec.count = 4
     pack = Pack([Node(ResOperation(rop.GUARD_TRUE, [vec]), 0),
                  Node(ResOperation(rop.GUARD_TRUE, [vec]), 1),
                  Node(ResOperation(rop.GUARD_TRUE, [vec]), 2),
                  Node(ResOperation(rop.GUARD_TRUE, [vec]), 3),
                  Node(ResOperation(rop.GUARD_TRUE, [vec]), 4),
                  Node(ResOperation(rop.GUARD_TRUE, [vec]), 5),
                 ])
     assert pack.pack_load(16) == 24-16
     assert pack.pack_load(8) == 24-8
     assert pack.pack_load(32) == 24-32
     assert pack.opcount_filling_vector_register(16) == 4
     ops, newops = pack.slice_operations(16)
     assert len(ops) == 4
     assert len(newops) == 2
     assert pack.opcount_filling_vector_register(8) == 2
     ops, newops = pack.slice_operations(8)
     assert len(ops) == 2
     assert len(newops) == 4
Ejemplo n.º 55
0
 def record(self, opnum, argboxes, value, descr=None):
     op = ResOperation(opnum, argboxes, descr)
     if value is None:
         assert op.type == 'v'
     elif isinstance(value, bool):
         assert op.type == 'i'
         op.setint(int(value))
     elif lltype.typeOf(value) == lltype.Signed:
         assert op.type == 'i'
         op.setint(value)
     elif lltype.typeOf(value) is longlong.FLOATSTORAGE:
         assert op.type == 'f'
         op.setfloatstorage(value)
     else:
         assert lltype.typeOf(value) == llmemory.GCREF
         assert op.type == 'r'
         op.setref_base(value)
     self.operations.append(op)
     return op
Ejemplo n.º 56
0
 def remove_tested_failarg(self, op):
     opnum = op.getopnum()
     if not (opnum == rop.GUARD_TRUE or opnum == rop.GUARD_FALSE):
         return
     if op.getarg(0).is_vector():
         return
     try:
         i = op.getfailargs().index(op.getarg(0))
     except ValueError:
         return
     # The checked value is also in the failargs.  The front-end
     # tries not to produce it, but doesn't always succeed (and
     # it's hard to test all cases).  Rewrite it away.
     value = int(opnum == rop.GUARD_FALSE)
     op1 = ResOperation(rop.SAME_AS_I, [ConstInt(value)])
     op1.setint(value)
     self.emit_op(op1)
     lst = op.getfailargs()[:]
     lst[i] = op1
     newop = op.copy_and_change(opnum)
     newop.setfailargs(lst)
     self._changed_op = op
     self._changed_op_to = newop
Ejemplo n.º 57
0
 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
Ejemplo n.º 58
0
 def handle_malloc_operation(self, op):
     opnum = op.getopnum()
     if opnum == rop.NEW:
         self.handle_new_fixedsize(op.getdescr(), op)
     elif opnum == rop.NEW_WITH_VTABLE:
         descr = op.getdescr()
         self.handle_new_fixedsize(descr, op)
         if self.gc_ll_descr.fielddescr_vtable is not None:
             op = ResOperation(rop.SETFIELD_GC,
                               [op, ConstInt(descr.get_vtable())],
                               descr=self.gc_ll_descr.fielddescr_vtable)
             self.emit_op(op)
     elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         self.handle_new_array(descr, op)
     elif opnum == rop.NEWSTR:
         self.handle_new_array(self.gc_ll_descr.str_descr, op,
                               kind=FLAG_STR)
     elif opnum == rop.NEWUNICODE:
         self.handle_new_array(self.gc_ll_descr.unicode_descr, op,
                               kind=FLAG_UNICODE)
     else:
         raise NotImplementedError(op.getopname())
Ejemplo n.º 59
0
def compile_simple_loop(metainterp, greenkey, start, inputargs, ops, jumpargs,
                        enable_opts):
    from rpython.jit.metainterp.optimizeopt import optimize_trace

    jitdriver_sd = metainterp.jitdriver_sd
    metainterp_sd = metainterp.staticdata
    jitcell_token = make_jitcell_token(jitdriver_sd)
    label = ResOperation(rop.LABEL, inputargs[:], descr=jitcell_token)
    jump_op = ResOperation(rop.JUMP, jumpargs[:], descr=jitcell_token)
    call_pure_results = metainterp.call_pure_results
    data = SimpleCompileData(label, ops + [jump_op],
                                 call_pure_results=call_pure_results,
                                 enable_opts=enable_opts)
    try:
        loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd,
                                        data, metainterp.box_names_memo)
    except InvalidLoop:
        return None
    loop = create_empty_loop(metainterp)
    loop.original_jitcell_token = jitcell_token
    loop.inputargs = loop_info.inputargs
    if loop_info.quasi_immutable_deps:
        loop.quasi_immutable_deps = loop_info.quasi_immutable_deps
    jump_op = ops[-1]
    target_token = TargetToken(jitcell_token)
    target_token.original_jitcell_token = jitcell_token
    label = ResOperation(rop.LABEL, loop_info.inputargs[:], descr=target_token)
    jump_op.setdescr(target_token)
    loop.operations = [label] + ops
    if not we_are_translated():
        loop.check_consistency()
    jitcell_token.target_tokens = [target_token]
    send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop",
                         inputargs, metainterp.box_names_memo)
    record_loop_or_bridge(metainterp_sd, loop)
    return target_token
Ejemplo n.º 60
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     builder.fakemetainterp.ovf_flag = False
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp.ovf_flag:   # overflow detected
         op = ResOperation(rop.GUARD_OVERFLOW, [])
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [])
     op.setdescr(builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)