예제 #1
0
def find_natural_loops(func, cfg=None):
    """Return a loop nesting forest for the given function ([Loop])"""
    cfg = cfg or cfa.cfg(func)
    dominators = cfa.compute_dominators(func, cfg)

    loops = []
    loop_stack = []
    for block in func.blocks:
        ### Look for incoming back-edge
        for pred in cfg.predecessors(block):
            if block in dominators[pred]:
                # We dominate an incoming block, this means there is a
                # back-edge (pred, block)
                loop_stack.append(Loop([block]))

        ### Populate Loop
        if loop_stack:
            loop = loop_stack[-1]
            head = loop.blocks[0]
            if head in dominators[block] and head != block:
                # Dominated by loop header, add
                loop.blocks.append(block)

            if head in cfg[block]:
                loop_stack.pop()
                if loop_stack:
                    # update outer loop
                    loop_stack[-1].blocks.extend(loop.blocks)
                    loop_stack[-1].children.append(loop)
                else:
                    # outermost loop, add to forest
                    loops.append(loop)

    assert not loop_stack
    return loops
예제 #2
0
def find_natural_loops(func, cfg=None):
    """Return a loop nesting forest for the given function ([Loop])"""
    cfg = cfg or cfa.cfg(func)
    dominators = cfa.compute_dominators(func, cfg)

    loops = []
    loop_stack = []
    for block in func.blocks:
        ### Look for incoming back-edge
        for pred in cfg.predecessors(block):
            if block in dominators[pred]:
                # We dominate an incoming block, this means there is a
                # back-edge (pred, block)
                loop_stack.append(Loop([block]))

        ### Populate Loop
        if loop_stack:
            loop = loop_stack[-1]
            head = loop.blocks[0]
            if head in dominators[block] and head != block:
                # Dominated by loop header, add
                loop.blocks.append(block)

            if head in cfg[block]:
                loop_stack.pop()
                if loop_stack:
                    # update outer loop
                    loop_stack[-1].blocks.extend(loop.blocks)
                    loop_stack[-1].children.append(loop)
                else:
                    # outermost loop, add to forest
                    loops.append(loop)

    assert not loop_stack
    return loops
예제 #3
0
def verify_block_order(func):
    """Verify block order according to dominator tree"""
    from pykit.analysis import cfa

    flow = cfa.cfg(func)
    dominators = cfa.compute_dominators(func, flow)

    visited = set()
    for block in func.blocks:
        visited.add(block.name)
        for dominator in dominators[block.name]:
            if dominator not in visited:
                raise VerifyError("Dominator %s does not precede block %s" % (
                                                        dominator, block.name))
예제 #4
0
def verify_block_order(func):
    """Verify block order according to dominator tree"""
    from pykit.analysis import cfa

    flow = cfa.cfg(func)
    dominators = cfa.compute_dominators(func, flow)

    visited = set()
    for block in func.blocks:
        visited.add(block.name)
        for dominator in dominators[block.name]:
            if dominator not in visited:
                raise VerifyError("Dominator %s does not precede block %s" % (
                                                        dominator, block.name))