Пример #1
0
    def produce_potential_short_preamble_ops(self, sb):
        ops = self.optimizer._newoperations
        for i, op in enumerate(ops):
            if rop.is_always_pure(op.opnum):
                sb.add_pure_op(op)
            if rop.is_ovf(
                    op.opnum) and ops[i +
                                      1].getopnum() == rop.GUARD_NO_OVERFLOW:
                sb.add_pure_op(op)
        for i in self.call_pure_positions:
            op = ops[i]
            # don't move call_pure_with_exception in the short preamble...
            # issue #2015

            # Also, don't move cond_call_value in the short preamble.
            # The issue there is that it's usually pointless to try to
            # because the 'value' argument is typically not a loop
            # invariant, and would really need to be in order to end up
            # in the short preamble.  Maybe the code works anyway in the
            # other rare case, but better safe than sorry and don't try.
            effectinfo = op.getdescr().get_extra_info()
            if not effectinfo.check_can_raise(ignore_memoryerror=True):
                assert rop.is_call(op.opnum)
                if not OpHelpers.is_cond_call_value(op.opnum):
                    sb.add_pure_op(op)
Пример #2
0
def user_loop_bail_fast_path(loop, warmstate):
    """ In a fast path over the trace loop: try to prevent vecopt
        of spending time on a loop that will most probably fail.
    """

    resop_count = 0 # the count of operations minus debug_merge_points
    vector_instr = 0
    guard_count = 0
    at_least_one_array_access = True
    for i,op in enumerate(loop.operations):
        if rop.is_jit_debug(op.opnum):
            continue

        if op.vector >= 0 and not rop.is_guard(op.opnum):
            vector_instr += 1

        resop_count += 1

        if op.is_primitive_array_access():
            at_least_one_array_access = True

        if rop.is_call(op.opnum) or rop.is_call_assembler(op.opnum):
            return True

        if rop.is_guard(op.opnum):
            guard_count += 1

    if not at_least_one_array_access:
        return True

    return False
Пример #3
0
    def fake_allocate(self, loop):
        from rpython.jit.backend.x86.jump import remap_frame_layout
        def emit(*args):
            self.assembler.emitted.append(args)
        for i, op in enumerate(loop.operations):
            self.rm.position = i
            opnum = op.getopnum()
            opname = op.getopname()
            if rop.is_comparison(opnum):
                locs = [self.loc(x) for x in op.getarglist()]
                loc = self.force_allocate_reg_or_cc(op)
                emit(opname, loc, locs)
            elif opname.startswith("int_"):
                locs = [self.loc(x) for x in op.getarglist()]
                loc = self.rm.force_result_in_reg(
                    op, op.getarg(0), op.getarglist())
                emit(opname, loc, locs[1:])
            elif op.is_guard():
                fail_locs = [self.loc(x) for x in op.getfailargs()]
                emit(opname, self.loc(op.getarg(0)), fail_locs)
            elif rop.is_call(opnum):
                # calling convention!
                src_locs = [self.loc(x) for x in op.getarglist()[1:]]
                self.rm.before_call()
                loc = self.rm.after_call(op)
                dst_locs = [r1, r2, r3][:len(src_locs)]
                remap_frame_layout(self.assembler, src_locs, dst_locs, r8)
                emit(opname, loc, dst_locs)
            elif opname == "label":
                descr = op.getdescr()
                locs = [self.loc(x) for x in op.getarglist()]
                emit(opname, locs)
                descr._fake_arglocs = locs
                lastop = loop.operations[-1]
                if lastop.getopname() == "jump" and lastop.getdescr() is descr:
                    # now we know the places, add hints
                    for i, r in enumerate(locs):
                        if isinstance(r, FakeReg):
                            self.longevity.fixed_register(
                                len(loop.operations) - 1, r, lastop.getarg(i))

            elif opname == "jump":
                src_locs = [self.loc(x) for x in op.getarglist()]
                dst_locs = op.getdescr()._fake_arglocs
                remap_frame_layout(self.assembler, src_locs, dst_locs, r8)
                emit("jump", dst_locs)
            else:
                locs = [self.loc(x) for x in op.getarglist()]
                if op.type != "v":
                    loc = self.rm.force_allocate_reg(op)
                    emit(opname, loc, locs)
                else:
                    emit(opname, locs)
            self.possibly_free_vars_for_op(op)
        return self.assembler.emitted
Пример #4
0
 def add_op_to_short(self, sb):
     op = self.res
     arglist = []
     for arg in op.getarglist():
         newarg = sb.produce_arg(arg)
         if newarg is None:
             return None
         arglist.append(newarg)
     if rop.is_call(op.opnum):
         opnum = OpHelpers.call_pure_for_descr(op.getdescr())
     else:
         opnum = op.getopnum()
     return ProducedShortOp(self, op.copy_and_change(opnum, args=arglist))
Пример #5
0
 def add_op_to_short(self, sb):
     op = self.res
     arglist = []
     for arg in op.getarglist():
         newarg = sb.produce_arg(arg)
         if newarg is None:
             return None
         arglist.append(newarg)
     if rop.is_call(op.opnum):
         opnum = OpHelpers.call_pure_for_descr(op.getdescr())
     else:
         opnum = op.getopnum()
     return ProducedShortOp(self, op.copy_and_change(opnum, args=arglist))
Пример #6
0
 def produce_op(self, opt, preamble_op, exported_infos, invented_name):
     optpure = opt.optimizer.optpure
     if optpure is None:
         return
     if invented_name:
         op = self.orig_op.copy_and_change(self.orig_op.getopnum())
         op.set_forwarded(self.res)
     else:
         op = self.res
     if rop.is_call(preamble_op.opnum):
         optpure.extra_call_pure.append(
             PreambleOp(op, preamble_op, invented_name))
     else:
         opt.pure(op.getopnum(), PreambleOp(op, preamble_op, invented_name))
Пример #7
0
 def _add_fixed_registers(self):
     for i, op in enumerate(self.operations):
         opnum = op.getopnum()
         opname = op.getopname()
         args = op.getarglist()
         if rop.is_call(opnum):
             # calling convention!
             arglist = op.getarglist()[1:]
             for arg, reg in zip(arglist + [None] * (3 - len(arglist)), [r1, r2, r3]):
                 self.longevity.fixed_register(i, reg, arg)
             self.longevity.fixed_register(i, r0, op)
         elif opname.startswith("int_"):
             if not args[0].is_constant():
                 self.longevity.try_use_same_register(args[0], op)
Пример #8
0
 def produce_op(self, opt, preamble_op, exported_infos, invented_name):
     optpure = opt.optimizer.optpure
     if optpure is None:
         return
     if invented_name:
         op = self.orig_op.copy_and_change(self.orig_op.getopnum())
         op.set_forwarded(self.res)
     else:
         op = self.res
     if rop.is_call(preamble_op.opnum):
         optpure.extra_call_pure.append(PreambleOp(op, preamble_op,
                                                   invented_name))
     else:
         opt.pure(op.getopnum(), PreambleOp(op, preamble_op,
                                            invented_name))
Пример #9
0
    def produce_potential_short_preamble_ops(self, sb):
        ops = self.optimizer._newoperations
        for i, op in enumerate(ops):
            if rop.is_always_pure(op.opnum):
                sb.add_pure_op(op)
            if rop.is_ovf(
                    op.opnum) and ops[i +
                                      1].getopnum() == rop.GUARD_NO_OVERFLOW:
                sb.add_pure_op(op)
        for i in self.call_pure_positions:
            op = ops[i]
            # don't move call_pure_with_exception in the short preamble...
            # issue #2015

            effectinfo = op.getdescr().get_extra_info()
            if not effectinfo.check_can_raise(ignore_memoryerror=True):
                assert rop.is_call(op.opnum)
                sb.add_pure_op(op)
Пример #10
0
 def emitting_operation(self, op):
     if rop.has_no_side_effect(op.opnum):
         return
     if rop.is_ovf(op.opnum):
         return
     if rop.is_guard(op.opnum):
         self.optimizer.pendingfields = (self.force_lazy_sets_for_guard())
         return
     opnum = op.getopnum()
     if (opnum == rop.SETFIELD_GC or  # handled specially
             opnum == rop.SETFIELD_RAW or  # no effect on GC struct/array
             opnum == rop.SETARRAYITEM_GC or  # handled specially
             opnum == rop.SETARRAYITEM_RAW or  # no effect on GC struct
             opnum == rop.SETINTERIORFIELD_RAW or  # no effect on GC struct
             opnum == rop.RAW_STORE or  # no effect on GC struct
             opnum == rop.STRSETITEM or  # no effect on GC struct/array
             opnum == rop.UNICODESETITEM or  # no effect on GC struct/array
             opnum == rop.DEBUG_MERGE_POINT or  # no effect whatsoever
             opnum == rop.JIT_DEBUG or  # no effect whatsoever
             opnum == rop.ENTER_PORTAL_FRAME or  # no effect whatsoever
             opnum == rop.LEAVE_PORTAL_FRAME or  # no effect whatsoever
             opnum == rop.COPYSTRCONTENT or  # no effect on GC struct/array
             opnum == rop.COPYUNICODECONTENT
             or  # no effect on GC struct/array
             opnum
             == rop.CHECK_MEMORY_ERROR):  # may only abort the whole loop
         return
     if rop.is_call(op.opnum):
         if rop.is_call_assembler(op.getopnum()):
             self._seen_guard_not_invalidated = False
         else:
             effectinfo = op.getdescr().get_extra_info()
             if effectinfo.check_can_invalidate():
                 self._seen_guard_not_invalidated = False
             if not effectinfo.has_random_effects():
                 self.force_from_effectinfo(effectinfo)
                 return
     self.force_all_lazy_sets()
     self.clean_caches()
Пример #11
0
 def emitting_operation(self, op):
     if rop.has_no_side_effect(op.opnum):
         return
     if rop.is_ovf(op.opnum):
         return
     if rop.is_guard(op.opnum):
         self.optimizer.pendingfields = (
             self.force_lazy_sets_for_guard())
         return
     opnum = op.getopnum()
     if (opnum == rop.SETFIELD_GC or          # handled specially
         opnum == rop.SETFIELD_RAW or         # no effect on GC struct/array
         opnum == rop.SETARRAYITEM_GC or      # handled specially
         opnum == rop.SETARRAYITEM_RAW or     # no effect on GC struct
         opnum == rop.SETINTERIORFIELD_RAW or # no effect on GC struct
         opnum == rop.RAW_STORE or            # no effect on GC struct
         opnum == rop.STRSETITEM or           # no effect on GC struct/array
         opnum == rop.UNICODESETITEM or       # no effect on GC struct/array
         opnum == rop.DEBUG_MERGE_POINT or    # no effect whatsoever
         opnum == rop.JIT_DEBUG or            # no effect whatsoever
         opnum == rop.ENTER_PORTAL_FRAME or   # no effect whatsoever
         opnum == rop.LEAVE_PORTAL_FRAME or   # no effect whatsoever
         opnum == rop.COPYSTRCONTENT or       # no effect on GC struct/array
         opnum == rop.COPYUNICODECONTENT or   # no effect on GC struct/array
         opnum == rop.CHECK_MEMORY_ERROR):    # may only abort the whole loop
         return
     if rop.is_call(op.opnum):
         if rop.is_call_assembler(op.getopnum()):
             self._seen_guard_not_invalidated = False
         else:
             effectinfo = op.getdescr().get_extra_info()
             if effectinfo.check_can_invalidate():
                 self._seen_guard_not_invalidated = False
             if not effectinfo.has_random_effects():
                 self.force_from_effectinfo(effectinfo)
                 return
     self.force_all_lazy_sets()
     self.clean_caches()
Пример #12
0
    def produce_potential_short_preamble_ops(self, sb):
        ops = self.optimizer._newoperations
        for i, op in enumerate(ops):
            if rop.is_always_pure(op.opnum):
                sb.add_pure_op(op)
            if rop.is_ovf(op.opnum) and ops[i + 1].getopnum() == rop.GUARD_NO_OVERFLOW:
                sb.add_pure_op(op)
        for i in self.call_pure_positions:
            op = ops[i]
            # don't move call_pure_with_exception in the short preamble...
            # issue #2015

            # Also, don't move cond_call_value in the short preamble.
            # The issue there is that it's usually pointless to try to
            # because the 'value' argument is typically not a loop
            # invariant, and would really need to be in order to end up
            # in the short preamble.  Maybe the code works anyway in the
            # other rare case, but better safe than sorry and don't try.
            effectinfo = op.getdescr().get_extra_info()
            if not effectinfo.check_can_raise(ignore_memoryerror=True):
                assert rop.is_call(op.opnum)
                if not OpHelpers.is_cond_call_value(op.opnum):
                    sb.add_pure_op(op)