Exemplo n.º 1
0
def test_loop_1():
    v1 = BoxInt(); v2 = BoxInt(); v3 = BoxInt()
    v4 = BoxInt(); v5 = BoxInt(); v6 = BoxInt()
    loop = TreeLoop('loop_1')
    loop.inputargs = [v1, v2, v3]
    loop.operations = [
        ResOperation(rop.INT_IS_TRUE, [v1], v4),
        ResOperation(rop.GUARD_TRUE, [v4], None),
        ResOperation(rop.INT_ADD, [v2, v3], v5),
        ResOperation(rop.INT_SUB, [v1, ConstInt(1)], v6),
        ResOperation(rop.JUMP, [v6, v2, v5], None),
        ]
    loop.operations[-1].jump_target = loop
    loop.operations[1].suboperations = [
        ResOperation(rop.FAIL, [v3], None),
        ]
    cpu = LLVMCPU(None)
    cpu.setup_once()
    cpu.compile_operations(loop)
    cpu.set_future_value_int(0, 2**11)
    cpu.set_future_value_int(1, 3)
    cpu.set_future_value_int(2, 0)
    cpu.execute_operations(loop)
    assert cpu.get_latest_value_int(0) == 3*(2**11)
    cpu.set_future_value_int(0, 2**29)
    cpu.set_future_value_int(1, 3)
    cpu.set_future_value_int(2, 0)
    cpu.execute_operations(loop)
    assert cpu.get_latest_value_int(0) == 3*(2**29)
Exemplo n.º 2
0
def convert_old_style_to_targets(loop, jump):
    newloop = TreeLoop(loop.name)
    newloop.inputargs = loop.inputargs
    newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, None, descr=FakeDescr())] + \
                      loop.operations
    if not jump:
        assert newloop.operations[-1].getopnum() == rop.JUMP
        newloop.operations[-1] = ResOperation(rop.LABEL, newloop.operations[-1].getarglist(), None, descr=FakeDescr())
    return newloop
Exemplo n.º 3
0
def convert_old_style_to_targets(loop, jump):
    newloop = TreeLoop(loop.name)
    newloop.inputargs = loop.inputargs
    newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, None, descr=FakeDescr())] + \
                      loop.operations
    if not jump:
        assert newloop.operations[-1].getopnum() == rop.JUMP
        newloop.operations[-1] = ResOperation(rop.LABEL, newloop.operations[-1].getarglist(), None, descr=FakeDescr())
    return newloop
Exemplo n.º 4
0
def test_loop_2():
    cpu = LLVMCPU(None)
    cpu.setup_once()
    #
    v1 = BoxInt(); v2 = BoxInt()
    loop1 = TreeLoop('loop1')
    loop1.inputargs = [v1]
    loop1.operations = [
        ResOperation(rop.INT_ADD, [ConstInt(1), v1], v2),
        ResOperation(rop.FAIL, [v2], None),
        ]
    cpu.compile_operations(loop1)
    #
    cpu.set_future_value_int(0, 123)
    cpu.execute_operations(loop1)
    assert cpu.get_latest_value_int(0) == 124
    #
    v3 = BoxInt(); v4 = BoxInt(); v5 = BoxInt()
    loop2 = TreeLoop('loop2')
    loop2.inputargs = [v3, v4]
    loop2.operations = [
        ResOperation(rop.INT_SUB, [v3, v4], v5),
        ResOperation(rop.JUMP, [v5], None),
        ]
    loop2.operations[-1].jump_target = loop1
    cpu.compile_operations(loop2)
    #
    cpu.set_future_value_int(0, 1500)
    cpu.set_future_value_int(1, 60)
    cpu.execute_operations(loop2)
    assert cpu.get_latest_value_int(0) == 1441
    #
    # Now try to change the definition of loop1...
    loop1.operations = [
        ResOperation(rop.INT_ADD, [ConstInt(3), v1], v2),
        ResOperation(rop.FAIL, [v2], None),
        ]
    cpu.compile_operations(loop1)
    #
    cpu.set_future_value_int(0, 1500)
    cpu.set_future_value_int(1, 60)
    cpu.execute_operations(loop2)
    assert cpu.get_latest_value_int(0) == 1443    # should see the change
Exemplo n.º 5
0
def test_debug_merge_point():
    loop = TreeLoop('test')
    loop.inputargs = []
    loop.operations = [
        ResOperation(rop.DEBUG_MERGE_POINT, [], None),
        ResOperation(rop.FAIL, [], None),
        ]
    cpu = LLVMCPU(None)
    cpu.setup_once()
    cpu.compile_operations(loop)
    cpu.execute_operations(loop)
Exemplo n.º 6
0
    def build_random_loop(self, cpu, builder_factory, r, startvars):

        loop = TreeLoop('test_random_function')
        loop.inputargs = startvars[:]
        loop.operations = []
        loop.token = LoopToken()

        builder = builder_factory(cpu, loop, startvars[:])
        self.generate_ops(builder, r, loop, startvars)
        self.builder = builder
        self.loop = loop
        cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
Exemplo n.º 7
0
    def build_random_loop(self, cpu, builder_factory, r, startvars):

        loop = TreeLoop('test_random_function')
        loop.inputargs = startvars[:]
        loop.operations = []
        loop.token = LoopToken()

        builder = builder_factory(cpu, loop, startvars[:])
        self.generate_ops(builder, r, loop, startvars)
        self.builder = builder
        self.loop = loop
        cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
Exemplo n.º 8
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
Exemplo n.º 9
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
Exemplo n.º 10
0
    def build_random_loop(self, cpu, builder_factory, r, startvars, allow_delay):

        loop = TreeLoop('test_random_function')
        loop.inputargs = startvars[:]
        loop.operations = []
        loop._jitcelltoken = JitCellToken()
        builder = builder_factory(cpu, loop, startvars[:])
        if allow_delay:
            needs_a_label = True
        else:
            self.insert_label(loop, 0, r)
            needs_a_label = False
        self.generate_ops(builder, r, loop, startvars, needs_a_label=needs_a_label)
        self.builder = builder
        self.loop = loop
        dump(loop)
        cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken)
Exemplo n.º 11
0
def test_simple_case():
    v1 = BoxInt()
    v2 = BoxInt()
    v3 = BoxInt()
    v4 = BoxInt()
    loop = TreeLoop('test')
    loop.inputargs = [v1]
    loop.operations = [
        ResOperation(rop.INT_ADD, [v1, v1], v2),
        ResOperation(rop.INT_INVERT, [v2], v3),
        ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4),
        ResOperation(rop.FAIL, [v4, v3], None),
        ]
    cpu = LLVMCPU(None)
    cpu.setup_once()
    cpu.compile_operations(loop)
    cpu.set_future_value_int(0, 19)
    cpu.execute_operations(loop)
    assert cpu.get_latest_value_int(0) == (19 >> 3)
    assert cpu.get_latest_value_int(1) == (~38)
Exemplo n.º 12
0
    def build_random_loop(self, cpu, builder_factory, r, startvars,
                          allow_delay):

        loop = TreeLoop('test_random_function')
        loop.inputargs = startvars[:]
        loop.operations = []
        loop._jitcelltoken = JitCellToken()
        builder = builder_factory(cpu, loop, startvars[:])
        if allow_delay:
            needs_a_label = True
        else:
            self.insert_label(loop, 0, r)
            needs_a_label = False
        self.generate_ops(builder,
                          r,
                          loop,
                          startvars,
                          needs_a_label=needs_a_label)
        self.builder = builder
        self.loop = loop
        dump(loop)
        cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken)
Exemplo n.º 13
0
    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()
Exemplo n.º 14
0
Arquivo: unroll.py Projeto: 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()
Exemplo n.º 15
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