Пример #1
0
    def unroll_and_optimize(self, loop, call_pure_results=None):
        operations =  loop.operations
        jumpop = operations[-1]
        assert jumpop.getopnum() == rop.JUMP
        inputargs = loop.inputargs

        jump_args = jumpop.getarglist()[:]
        operations = operations[:-1]
        cloned_operations = [op.clone() for op in operations]

        preamble = TreeLoop('preamble')
        preamble.inputargs = inputargs
        preamble.resume_at_jump_descr = FakeDescrWithSnapshot()

        token = JitCellToken()
        preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \
                              operations +  \
                              [ResOperation(rop.LABEL, jump_args, None, descr=token)]
        self._do_optimize_loop(preamble, call_pure_results)

        assert preamble.operations[-1].getopnum() == rop.LABEL

        inliner = Inliner(inputargs, jump_args)
        loop.resume_at_jump_descr = preamble.resume_at_jump_descr
        loop.operations = [preamble.operations[-1]] + \
                          [inliner.inline_op(op, clone=False) for op in cloned_operations] + \
                          [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args],
                                        None, descr=token)]
                          #[inliner.inline_op(jumpop)]
        assert loop.operations[-1].getopnum() == rop.JUMP
        assert loop.operations[0].getopnum() == rop.LABEL
        loop.inputargs = loop.operations[0].getarglist()

        self._do_optimize_loop(loop, call_pure_results)
        extra_same_as = []
        while loop.operations[0].getopnum() != rop.LABEL:
            extra_same_as.append(loop.operations[0])
            del loop.operations[0]

        # Hack to prevent random order of same_as ops
        extra_same_as.sort(key=lambda op: str(preamble.operations).find(str(op.getarg(0))))

        for op in extra_same_as:
            preamble.operations.insert(-1, op)

        return preamble
Пример #2
0
    def optimize_loop(self, ops, expected, expected_shorts=None):
        loop = self.parse(ops)
        if expected != "crash!":
            expected = self.parse(expected)

        part = TreeLoop('part')
        part.inputargs = loop.inputargs
        part.resume_at_jump_descr = FakeDescrWithSnapshot()
        token = loop.original_jitcell_token

        optimized = TreeLoop('optimized')
        optimized.inputargs = loop.inputargs
        optimized.operations = []

        labels = [i for i, op in enumerate(loop.operations) \
                  if op.getopnum()==rop.LABEL]
        prv = 0
        last_label = []
        for nxt in labels + [len(loop.operations)]:
            assert prv != nxt
            operations = last_label + loop.operations[prv:nxt]
            if nxt < len(loop.operations):
                label = loop.operations[nxt]
                assert label.getopnum() == rop.LABEL
                if label.getdescr() is None:
                    label.setdescr(token)
                operations.append(label)
            part.operations = operations

            self._do_optimize_loop(part, None)
            if part.operations[-1].getopnum() == rop.LABEL:
                last_label = [part.operations.pop()]
            else:
                last_label = []

            optimized.operations.extend(part.operations)
            prv = nxt + 1

        #
        print
        print "Optimized:"
        if optimized.operations:
            print '\n'.join([str(o) for o in optimized.operations])
        else:
            print 'Failed!'
        print

        shorts = [op.getdescr().short_preamble
                  for op in optimized.operations
                  if op.getopnum() == rop.LABEL]

        if expected_shorts:
            for short in shorts:
                print
                print "Short preamble:"
                print '\n'.join([str(o) for o in short])


        assert expected != "crash!", "should have raised an exception"
        self.assert_equal(optimized, expected)

        if expected_shorts:
            assert len(shorts) == len(expected_shorts)
            for short, expected_short in zip(shorts, expected_shorts):
                expected_short = self.parse(expected_short)
                short_preamble = TreeLoop('short preamble')
                assert short[0].getopnum() == rop.LABEL
                short_preamble.inputargs = short[0].getarglist()
                short_preamble.operations = short
                self.assert_equal(short_preamble, expected_short,
                                  text_right='expected short preamble')


        return optimized