Exemple #1
0
def malloc_to_stack(t):
    adi = AbstractDataFlowInterpreter(t)
    for graph in t.graphs:
        if graph.startblock not in adi.flown_blocks:
            adi.schedule_function(graph)
            adi.complete()
    for graph in t.graphs:
        loop_blocks = support.find_loop_blocks(graph)
        for block, op in graph.iterblockops():
            if op.opname == 'malloc':
                STRUCT = op.args[0].value
                # must not remove mallocs of structures that have a RTTI with a destructor
                try:
                    destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
                    if destr_ptr:
                        continue
                except (ValueError, AttributeError), e:
                    pass
                varstate = adi.getstate(op.result)
                assert len(varstate.creation_points) == 1
                crep = varstate.creation_points.keys()[0]
                if not crep.escapes:
                    if block not in loop_blocks:
                        print "moving object from heap to stack %s in %s" % (op, graph.name)
                        op.opname = 'flavored_malloc'
                        op.args.insert(0, inputconst(lltype.Void, 'stack'))
                    else:
                        print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
Exemple #2
0
def malloc_to_stack(t):
    adi = AbstractDataFlowInterpreter(t)
    for graph in t.graphs:
        if graph.startblock not in adi.flown_blocks:
            adi.schedule_function(graph)
            adi.complete()
    for graph in t.graphs:
        loop_blocks = support.find_loop_blocks(graph)
        for block, op in graph.iterblockops():
            if op.opname != 'malloc':
                continue
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError), e:
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep = varstate.creation_points.keys()[0]
            if not crep.escapes:
                if block not in loop_blocks:
                    print "moving object from heap to stack %s in %s" % (op, graph.name)
                    flags = op.args[1].value
                    assert flags == {'flavor': 'gc'}
                    op.args[1] = Constant({'flavor': 'stack'}, lltype.Void)
                else:
                    print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
Exemple #3
0
def test_find_loop_blocks_simple():
    def f(a):
        if a <= 0:
            return 1
        return f(a - 1)
    t = TranslationContext()
    t.buildannotator().build_types(f, [int])
    t.buildrtyper().specialize()
    graph = graphof(t, f)
    backedges = find_backedges(graph)
    assert backedges == []
    loop_blocks = find_loop_blocks(graph)
    assert len(loop_blocks) == 0
Exemple #4
0
def test_find_loop_blocks():
    def f(k):
        result = 0
        for i in range(k):
            result += 1
        for j in range(k):
            result += 1
        return result
    t = TranslationContext()
    t.buildannotator().build_types(f, [int])
    t.buildrtyper().specialize()
    graph = graphof(t, f)
    loop_blocks = find_loop_blocks(graph)
    assert len(loop_blocks) == 4
Exemple #5
0
def measure_median_execution_cost(graph):
    blocks = []
    blockmap = {}
    for block in graph.iterblocks():
        blockmap[block] = len(blocks)
        blocks.append(block)
    loops = find_loop_blocks(graph)
    M = sparsemat.SparseMatrix(len(blocks))
    vector = []
    for i, block in enumerate(blocks):
        vector.append(block_weight(block))
        M[i, i] = 1
        if block.exits:
            if block not in loops:
                current_loop_start = None
            else:
                current_loop_start = loops[block]
            loop_exits = []
            for link in block.exits:
                if (link.target in loops and
                    loops[link.target] is current_loop_start):
                    loop_exits.append(link)
            if len(loop_exits) and len(loop_exits) < len(block.exits):
                f = 0.3 / (len(block.exits) - len(loop_exits))
                b = 0.7 / len(loop_exits)
            else:
                b = f = 1.0 / len(block.exits)
            for link in block.exits:
                if (link.target in loops and
                    loops[link.target] is current_loop_start):
                    M[i, blockmap[link.target]] -= b
                else:
                    M[i, blockmap[link.target]] -= f
    try:
        Solution = M.solve(vector)
    except ValueError:
        return sys.maxint
    else:
        res = Solution[blockmap[graph.startblock]]
        assert res >= 0
        return res
Exemple #6
0
def measure_median_execution_cost(graph):
    blocks = []
    blockmap = {}
    for block in graph.iterblocks():
        blockmap[block] = len(blocks)
        blocks.append(block)
    loops = find_loop_blocks(graph)
    M = sparsemat.SparseMatrix(len(blocks))
    vector = []
    for i, block in enumerate(blocks):
        vector.append(block_weight(block))
        M[i, i] = 1
        if block.exits:
            if block not in loops:
                current_loop_start = None
            else:
                current_loop_start = loops[block]
            loop_exits = []
            for link in block.exits:
                if (link.target in loops
                        and loops[link.target] is current_loop_start):
                    loop_exits.append(link)
            if len(loop_exits) and len(loop_exits) < len(block.exits):
                f = 0.3 / (len(block.exits) - len(loop_exits))
                b = 0.7 / len(loop_exits)
            else:
                b = f = 1.0 / len(block.exits)
            for link in block.exits:
                if (link.target in loops
                        and loops[link.target] is current_loop_start):
                    M[i, blockmap[link.target]] -= b
                else:
                    M[i, blockmap[link.target]] -= f
    try:
        Solution = M.solve(vector)
    except ValueError:
        return sys.maxint
    else:
        res = Solution[blockmap[graph.startblock]]
        assert res >= 0
        return res
Exemple #7
0
def test_find_loop_blocks2():
    class A:
        pass
    def f(n):
        a1 = A()
        a1.x = 1
        a2 = A()
        a2.x = 2
        if n > 0:
            a = a1
        else:
            a = a2
        return a.x
    t = TranslationContext()
    t.buildannotator().build_types(f, [int])
    t.buildrtyper().specialize()
    graph = graphof(t, f)
    backedges = find_backedges(graph)
    assert backedges == []
    loop_blocks = find_loop_blocks(graph)
    assert len(loop_blocks) == 0
Exemple #8
0
def test_find_loop_blocks3():
    import os
    def ps(loops):
        return 42.0, 42.1
    def f(loops):
        benchtime, stones = ps(abs(loops))
        s = '' # annotator happiness
        if loops >= 0:
            s = ("RPystone(%s) time for %d passes = %f" %
                 (23, loops, benchtime) + '\n' + (
                 "This machine benchmarks at %f pystones/second" % stones))
        os.write(1, s)
        if loops == 12345:
            f(loops-1)
    t = TranslationContext()
    t.buildannotator().build_types(f, [int])
    t.buildrtyper().specialize()
    graph = graphof(t, f)
    backedges = find_backedges(graph)
    assert backedges == []
    loop_blocks = find_loop_blocks(graph)
    assert len(loop_blocks) == 0
Exemple #9
0
 def transform(self):
     assert not support.find_loop_blocks(self.graph)
     for i,var in enumerate(self.startblock.inputargs):
         self.vartonode[var] = ArgumentNode(i)
     self.transform_block(self.startblock)
     return self.get_node(self.returnblock.inputargs[0])