コード例 #1
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(BasicFailDescr())
     op.setfailargs([])
     return op
コード例 #2
0
ファイル: test_random.py プロジェクト: purepython/pypy
 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(BasicFailDescr())
     op.setfailargs([])
     return op
コード例 #3
0
ファイル: test_random.py プロジェクト: purepython/pypy
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp._got_exc:  # overflow detected
         assert isinstance(builder.fakemetainterp._got_exc, OverflowError)
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # 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, [], None)
     op.setdescr(BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
コード例 #4
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp._got_exc:  # overflow detected
         assert isinstance(builder.fakemetainterp._got_exc, OverflowError)
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # 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, [], None)
     op.setdescr(BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
コード例 #5
0
    def propagate_all_forward(self):
        loop = self.optimizer.loop
        self.optimizer.clear_newoperations()

        start_label = loop.operations[0]
        if start_label.getopnum() == rop.LABEL:
            loop.operations = loop.operations[1:]
            # We need to emit the label op before import_state() as emitting it
            # will clear heap caches
            self.optimizer.send_extra_operation(start_label)
        else:
            start_label = None            

        jumpop = loop.operations[-1]
        if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL:
            loop.operations = loop.operations[:-1]
        else:
            jumpop = None

        self.import_state(start_label)
        self.optimizer.propagate_all_forward(clear=False)

        if not jumpop:
            return

        cell_token = jumpop.getdescr()
        assert isinstance(cell_token, JitCellToken)
        stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token))

        
        if jumpop.getopnum() == rop.JUMP:
            if self.jump_to_already_compiled_trace(jumpop):
                # Found a compiled trace to jump to
                if self.short:
                    # Construct our short preamble
                    assert start_label
                    self.close_bridge(start_label)
                return

            if start_label and self.jump_to_start_label(start_label, stop_label):
                # Initial label matches, jump to it
                jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None,
                                      descr=start_label.getdescr())
                if self.short:
                    # Construct our short preamble
                    self.close_loop(start_label, jumpop)
                else:
                    self.optimizer.send_extra_operation(jumpop)
                return

            if cell_token.target_tokens:
                limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
                if cell_token.retraced_count < limit:
                    cell_token.retraced_count += 1
                    debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit))
                else:
                    debug_print("Retrace count reached, jumping to preamble")
                    assert cell_token.target_tokens[0].virtual_state is None
                    jumpop.setdescr(cell_token.target_tokens[0])
                    self.optimizer.send_extra_operation(jumpop)
                    return

        # Found nothing to jump to, emit a label instead
        
        if self.short:
            # Construct our short preamble
            assert start_label
            self.close_bridge(start_label)

        self.optimizer.flush()
        KillHugeIntBounds(self.optimizer).apply()

        loop.operations = self.optimizer.get_newoperations()
        self.export_state(stop_label)
        loop.operations.append(stop_label)
コード例 #6
0
ファイル: unroll.py プロジェクト: gorakhargosh/pypy
    def propagate_all_forward(self):
        loop = self.optimizer.loop
        jumpop = loop.operations[-1]
        if jumpop.getopnum() == rop.JUMP:
            loop.operations = loop.operations[:-1]
        else:
            loopop = None

        self.optimizer.propagate_all_forward()

        if jumpop:
            assert jumpop.getdescr() is loop.token
            jump_args = jumpop.getarglist()
            jumpop.initarglist([])
            self.optimizer.flush()

            KillHugeIntBounds(self.optimizer).apply()

            loop.preamble.operations = self.optimizer.newoperations
            jump_args = [self.getvalue(a).get_key_box() for a in jump_args]

            start_resumedescr = loop.preamble.start_resumedescr.clone_if_mutable()
            self.start_resumedescr = start_resumedescr
            assert isinstance(start_resumedescr, ResumeGuardDescr)
            start_resumedescr.rd_snapshot = self.fix_snapshot(loop, jump_args, start_resumedescr.rd_snapshot)

            modifier = VirtualStateAdder(self.optimizer)
            virtual_state = modifier.get_virtual_state(jump_args)

            values = [self.getvalue(arg) for arg in jump_args]
            inputargs = virtual_state.make_inputargs(values)
            short_inputargs = virtual_state.make_inputargs(values, keyboxes=True)

            self.constant_inputargs = {}
            for box in jump_args:
                const = self.get_constant_box(box)
                if const:
                    self.constant_inputargs[box] = const

            sb = ShortBoxes(self.optimizer, inputargs + self.constant_inputargs.keys())
            self.short_boxes = sb
            preamble_optimizer = self.optimizer
            loop.preamble.quasi_immutable_deps = self.optimizer.quasi_immutable_deps
            self.optimizer = self.optimizer.new()
            loop.quasi_immutable_deps = self.optimizer.quasi_immutable_deps

            logops = self.optimizer.loop.logops
            if logops:
                args = ", ".join([logops.repr_of_arg(arg) for arg in inputargs])
                debug_print("inputargs:       " + args)
                args = ", ".join([logops.repr_of_arg(arg) for arg in short_inputargs])
                debug_print("short inputargs: " + args)
                self.short_boxes.debug_print(logops)

            # Force virtuals amoung the jump_args of the preamble to get the
            # operations needed to setup the proper state of those virtuals
            # in the peeled loop
            inputarg_setup_ops = []
            preamble_optimizer.newoperations = []
            seen = {}
            for box in inputargs:
                if box in seen:
                    continue
                seen[box] = True
                value = preamble_optimizer.getvalue(box)
                inputarg_setup_ops.extend(value.make_guards(box))
            for box in short_inputargs:
                if box in seen:
                    continue
                seen[box] = True
                value = preamble_optimizer.getvalue(box)
                value.force_box()
            preamble_optimizer.flush()
            inputarg_setup_ops += preamble_optimizer.newoperations

            # Setup the state of the new optimizer by emiting the
            # short preamble operations and discarding the result
            self.optimizer.emitting_dissabled = True
            for op in 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:
                    # The order of these guards is not important as
                    # self.optimizer.emitting_dissabled is False
                    value = preamble_optimizer.getvalue(op.result)
                    for guard in value.make_guards(op.result):
                        self.optimizer.send_extra_operation(guard)
                    newresult = self.optimizer.getvalue(op.result).get_key_box()
                    if newresult is not op.result:
                        self.short_boxes.alias(newresult, op.result)
            self.optimizer.flush()
            self.optimizer.emitting_dissabled = False

            # XXX Hack to prevent the arraylen/strlen/unicodelen ops generated
            #     by value.make_guards() from ending up in pure_operations
            for key, op in self.optimizer.pure_operations.items():
                if not self.short_boxes.has_producer(op.result):
                    del self.optimizer.pure_operations[key]

            initial_inputargs_len = len(inputargs)
            self.inliner = Inliner(loop.inputargs, jump_args)

            short = self.inline(inputargs, self.cloned_operations, loop.inputargs, short_inputargs, virtual_state)

            loop.inputargs = inputargs
            args = [preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box() for a in inputargs]
            jmp = ResOperation(rop.JUMP, args, None)
            jmp.setdescr(loop.token)
            loop.preamble.operations.append(jmp)

            loop.operations = self.optimizer.newoperations
            maxguards = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.max_retrace_guards

            if self.optimizer.emitted_guards > maxguards:
                loop.preamble.token.retraced_count = sys.maxint

            if short:
                assert short[-1].getopnum() == rop.JUMP
                short[-1].setdescr(loop.token)

                # Turn guards into conditional jumps to the preamble
                for i in range(len(short)):
                    op = short[i]
                    if op.is_guard():
                        op = op.clone()
                        op.setfailargs(None)
                        descr = self.start_resumedescr.clone_if_mutable()
                        op.setdescr(descr)
                        short[i] = op

                short_loop = TreeLoop("short preamble")
                short_loop.inputargs = short_inputargs
                short_loop.operations = short

                # Clone ops and boxes to get private versions and
                boxmap = {}
                newargs = [None] * len(short_loop.inputargs)
                for i in range(len(short_loop.inputargs)):
                    a = short_loop.inputargs[i]
                    if a in boxmap:
                        newargs[i] = boxmap[a]
                    else:
                        newargs[i] = a.clonebox()
                        boxmap[a] = newargs[i]
                inliner = Inliner(short_loop.inputargs, newargs)
                for box, const in self.constant_inputargs.items():
                    inliner.argmap[box] = const
                short_loop.inputargs = newargs
                ops = [inliner.inline_op(op) for op in short_loop.operations]
                short_loop.operations = ops
                descr = self.start_resumedescr.clone_if_mutable()
                inliner.inline_descr_inplace(descr)
                short_loop.start_resumedescr = descr

                assert isinstance(loop.preamble.token, LoopToken)
                if loop.preamble.token.short_preamble:
                    loop.preamble.token.short_preamble.append(short_loop)
                else:
                    loop.preamble.token.short_preamble = [short_loop]
                short_loop.virtual_state = virtual_state

                # Forget the values to allow them to be freed
                for box in short_loop.inputargs:
                    box.forget_value()
                for op in short_loop.operations:
                    if op.result:
                        op.result.forget_value()
コード例 #7
0
ファイル: unroll.py プロジェクト: ieure/pypy
    def create_short_preamble(self, preamble, loop):
        #return None # Dissable

        preamble_ops = preamble.operations
        loop_ops = loop.operations

        boxmap = BoxMap()
        state = ExeState(self.optimizer)
        short_preamble = []
        loop_i = preamble_i = 0
        while preamble_i < len(preamble_ops):

            op = preamble_ops[preamble_i]
            try:
                newop = self.inliner.inline_op(op, ignore_result=True,
                                               ignore_failargs=True)
            except KeyError:
                debug_print("create_short_preamble failed due to",
                            "new boxes created during optimization.",
                            "op:", op.getopnum(),
                            "at preamble position: ", preamble_i,
                            "loop position: ", loop_i)
                return None
                
            if self.sameop(newop, loop_ops[loop_i]) \
               and loop_i < len(loop_ops):
                try:
                    boxmap.link_ops(op, loop_ops[loop_i])
                except ImpossibleLink:
                    debug_print("create_short_preamble failed due to",
                                "impossible link of "
                                "op:", op.getopnum(),
                                "at preamble position: ", preamble_i,
                                "loop position: ", loop_i)
                    return None
                loop_i += 1
            else:
                if not state.safe_to_move(op):
                    debug_print("create_short_preamble failed due to",
                                "unsafe op:", op.getopnum(),
                                "at preamble position: ", preamble_i,
                                "loop position: ", loop_i)
                    return None
                short_preamble.append(op)
                
            state.update(op)
            preamble_i += 1

        if loop_i < len(loop_ops):
            debug_print("create_short_preamble failed due to",
                        "loop contaning ops not in preamble"
                        "at position", loop_i)
            return None

        
        jumpargs = []
        for i in range(len(loop.inputargs)):
            try:
                jumpargs.append(boxmap.get_preamblebox(loop.inputargs[i]))
            except KeyError:
                debug_print("create_short_preamble failed due to",
                            "input arguments not located")
                return None

        jmp = ResOperation(rop.JUMP, jumpargs[:], None)
        jmp.setdescr(loop.token)
        short_preamble.append(jmp)

        # Check that boxes used as arguemts are produced.
        seen = {}
        for box in preamble.inputargs:
            seen[box] = True
        for op in short_preamble:
            for box in op.getarglist():
                if isinstance(box, Const):
                    continue
                if box not in seen:
                    debug_print("create_short_preamble failed due to",
                                "op arguments not produced")
                    return None
            if op.result:
                seen[op.result] = True
        
        return short_preamble
コード例 #8
0
ファイル: unroll.py プロジェクト: ieure/pypy
    def propagate_all_forward(self):
        loop = self.optimizer.loop
        jumpop = loop.operations[-1]
        if jumpop.getopnum() == rop.JUMP:
            loop.operations = loop.operations[:-1]
        else:
            loopop = None

        self.optimizer.propagate_all_forward()


        if jumpop:
            assert jumpop.getdescr() is loop.token
            jump_args = jumpop.getarglist()
            jumpop.initarglist([])
            #virtual_state = [self.getvalue(a).is_virtual() for a in jump_args]
            modifier = VirtualStateAdder(self.optimizer)
            virtual_state = modifier.get_virtual_state(jump_args)

            loop.preamble.operations = self.optimizer.newoperations
            loop.preamble.quasi_immutable_deps = (
                self.optimizer.quasi_immutable_deps)
            self.optimizer = self.optimizer.reconstruct_for_next_iteration()
            inputargs = self.inline(self.cloned_operations,
                                    loop.inputargs, jump_args)
            loop.inputargs = inputargs
            jmp = ResOperation(rop.JUMP, loop.inputargs[:], None)
            jmp.setdescr(loop.token)
            loop.preamble.operations.append(jmp)

            loop.operations = self.optimizer.newoperations
            loop.quasi_immutable_deps = self.optimizer.quasi_immutable_deps

            start_resumedescr = loop.preamble.start_resumedescr.clone_if_mutable()
            assert isinstance(start_resumedescr, ResumeGuardDescr)
            snapshot = start_resumedescr.rd_snapshot
            while snapshot is not None:
                snapshot_args = snapshot.boxes 
                new_snapshot_args = []
                for a in snapshot_args:
                    if not isinstance(a, Const):
                        a = loop.preamble.inputargs[jump_args.index(a)]
                    new_snapshot_args.append(a)
                snapshot.boxes = new_snapshot_args
                snapshot = snapshot.prev

            short = self.create_short_preamble(loop.preamble, loop)
            if short:
                if False:
                    # FIXME: This should save some memory but requires
                    # a lot of tests to be fixed...
                    loop.preamble.operations = short[:]

                # Turn guards into conditional jumps to the preamble
                for i in range(len(short)):
                    op = short[i]
                    if op.is_guard():
                        op = op.clone()
                        op.setfailargs(None)
                        op.setdescr(start_resumedescr.clone_if_mutable())
                        short[i] = op

                short_loop = TreeLoop('short preamble')
                short_loop.inputargs = loop.preamble.inputargs[:]
                short_loop.operations = short

                # Clone ops and boxes to get private versions and 
                newargs = [a.clonebox() for a in short_loop.inputargs]
                inliner = Inliner(short_loop.inputargs, newargs)
                short_loop.inputargs = newargs
                ops = [inliner.inline_op(op) for op in short_loop.operations]
                short_loop.operations = ops
                descr = start_resumedescr.clone_if_mutable()
                inliner.inline_descr_inplace(descr)
                short_loop.start_resumedescr = descr

                assert isinstance(loop.preamble.token, LoopToken)
                if loop.preamble.token.short_preamble:
                    loop.preamble.token.short_preamble.append(short_loop)
                else:
                    loop.preamble.token.short_preamble = [short_loop]
                short_loop.virtual_state = virtual_state

                # Forget the values to allow them to be freed
                for box in short_loop.inputargs:
                    box.forget_value()
                for op in short_loop.operations:
                    if op.result:
                        op.result.forget_value()