示例#1
0
def find_direct_dominated_preds(blocks, dominator, dom_frontier_node):
    preds = {successors(block[-1]): name for name, block in blocks.items()}
    succ = {name: successors(block[-1]) for name, block in blocks.items()}
    dom = get_dom(succ, list(blocks.keys())[0])

    results = set()
    for pred in preds[dom_frontier_node]:
        if pred in dom[dominator]:
            results.add(pred)
    return results
示例#2
0
def cfg_dot(bril, verbose):
    """Generate a GraphViz "dot" file showing the control flow graph for
    a Bril program.

    In `verbose` mode, include the instructions in the vertices.
    """
    for func in bril['functions']:
        print('digraph {} {{'.format(func['name']))

        blocks = block_map(form_blocks(func['instrs']))

        # Insert terminators into blocks that don't have them.
        add_terminators(blocks)

        # Add the vertices.
        for name, block in blocks.items():
            if verbose:
                import briltxt
                print(r'  {} [shape=box, xlabel="{}", label="{}\l"];'.format(
                    name,
                    name,
                    r'\l'.join(briltxt.instr_to_string(i) for i in block),
                ))
            else:
                print('  {};'.format(name))

        # Add the control-flow edges.
        for i, (name, block) in enumerate(blocks.items()):
            succ = successors(block[-1])
            for label in succ:
                print('  {} -> {};'.format(name, label))

        print('}')
示例#3
0
def convert_to_ssa(func):
    # return labeled blocks
    blocks = block_map(form_blocks(func['instrs']))
    # add entry block if required
    add_entry(blocks)
    # add terminators to block if required
    add_terminators(blocks)
    # get the successor of each block
    succ = {name: successors(block[-1]) for name, block in blocks.items()}
    # get the predecessor of each block
    pred = map_inv(succ)
    # get dominator of each block
    dom = get_dom(succ, list(blocks.keys())[0])
    # get dominate frontier of each block
    df = dom_fronts(dom, succ)
    # varaible map to block label
    defs = def_blocks(blocks)
    # get function type
    types = get_types(func)
    # get argument name
    arg_names = {a['name'] for a in func['args']} if 'args' in func else set()
    # find phi nodes
    phis = get_phis(blocks, df, defs)
    # rename variables
    phi_args, phi_dests = ssa_rename(blocks, phis, succ, dom_tree(dom),
                                     arg_names)
    # inserte phi nodes
    insert_phis(blocks, phi_args, phi_dests, types)
    # rebuild the updated blocks
    func['instrs'] = reassemble(blocks)
示例#4
0
def print_dom(bril, mode):
  for func in bril['functions']:
    # return labeled blocks
    blocks = block_map(form_blocks(func['instrs']))
    #for name, block in blocks.items():
    #  print(str(name)+":"+str(block))
    # add entry block if required
    add_entry(blocks)
    # add terminators to every block if required
    add_terminators(blocks)
    # get the successor of each block 
    succ = {name: successors(block[-1]) for name, block in blocks.items()}

    #for name, block in succ.items():
    #  print(str(name)+": "+str(block))
    dom = get_dom(succ, list(blocks.keys())[0])

    if mode == 'front':
      res = dom_fronts(dom, succ)
    elif mode == 'tree':
      res = dom_tree(dom)
    else:
      res = dom

    # Format as JSON for stable output.
    print(json.dumps(
      {k: sorted(list(v)) for k, v in res.items()},
      indent=2, sort_keys=True,
    ))
示例#5
0
def get_dom_dict(bril):
    for func in bril['functions']:
        blocks = block_map(form_blocks(func['instrs']))
        add_terminators(blocks)
        succ = {name: successors(block[-1]) for name, block in blocks.items()}
        dom = get_dom(succ, list(blocks.keys())[0])
    return dom
示例#6
0
def dfs_postorder(cfg, x):
    global post_max
    visit[x] = True
    for y in cfg.successors(x):
        if visit.get(y, None) is None:
            dfs_postorder(cfg, y)
    post_max += 1
    post_n[post_max] = x
    post_i[x] = post_max
示例#7
0
def get_closest(cfg, node, nodes):
    if len(nodes) == 1:
        return nodes.pop()
    min = 9000
    indx = post_i[node]
    closest = None
    for n in nodes:
        i = indx - post_i[n]
        if len(cfg.successors(n)) == 1:
            return n
        if i < min:
            min = i
            closest = n
    return closest
示例#8
0
def print_dom(bril):
    for func in bril['functions']:
        blocks = block_map(form_blocks(func['instrs']))
        add_terminators(blocks)
        succ = {name: successors(block[-1]) for name, block in blocks.items()}
        dom = get_dom(succ, list(blocks.keys())[0])

        # Format as JSON for stable output.
        print(
            json.dumps(
                {k: sorted(list(v))
                 for k, v in dom.items()},
                indent=2,
                sort_keys=True,
            ))
示例#9
0
文件: to_ssa.py 项目: RSenApps/bril
def func_to_ssa(func):
    blocks = block_map(form_blocks(func['instrs']))
    add_entry(blocks)
    add_terminators(blocks)
    succ = {name: successors(block[-1]) for name, block in blocks.items()}
    dom = get_dom(succ, list(blocks.keys())[0])

    df = dom_fronts(dom, succ)
    defs = def_blocks(blocks)
    types = get_types(func)
    arg_names = {a['name'] for a in func['args']} if 'args' in func else set()

    phis = get_phis(blocks, df, defs)
    phi_args, phi_dests = ssa_rename(blocks, phis, succ, dom_tree(dom),
                                     arg_names)
    insert_phis(blocks, phi_args, phi_dests, types)

    func['instrs'] = reassemble(blocks)
示例#10
0
文件: dom.py 项目: zhuguangxiang/bril
def print_dom(bril, mode):
    for func in bril['functions']:
        blocks = block_map(form_blocks(func['instrs']))
        add_entry(blocks)
        add_terminators(blocks)
        succ = {name: successors(block[-1]) for name, block in blocks.items()}
        dom = get_dom(succ, list(blocks.keys())[0])

        if mode == 'front':
            res = dom_fronts(dom, succ)
        elif mode == 'tree':
            res = dom_tree(dom)
        else:
            res = dom

        # Format as JSON for stable output.
        print(json.dumps(
            {k: sorted(list(v)) for k, v in res.items()},
            indent=2, sort_keys=True,
        ))
示例#11
0
def form_cfg(bril, verbose):
    """Generate a GraphViz "dot" file showing the control flow graph for
    a Bril program.

    In `verbose` mode, include the instructions in the vertices.
    """
    cfg = {}
    txt = open("update.bril", "w+")
    txt.write('main { \n')

    for func in bril['functions']:
        blocks = block_map(form_blocks(func['instrs']))

        # Insert terminators into blocks that don't have them.
        add_terminators(blocks)

        # Add the control-flow edges.
        for i, (name, block) in enumerate(blocks.items()):
            if verbose:
                import vriltxt
                block_name = r'  {} [shape=box, xlabel="{}", label="{}\l"];'.format(
                    name,
                    name,
                    r'\l'.join(vriltxt.instr_to_string(i) for i in block),
                )
                inbril = '{}:\n{};\n'.format(
                    name,
                    ';\n'.join(vriltxt.instr_to_string(i) for i in block))
            else:
                block_name = '{}'.format(name)
            edges = []
            succ = successors(block[-1])
            for label in succ:
                edges.append('{}'.format(label))
            cfg.update({block_name: edges})
            txt.write(inbril)

    print_cfg(cfg)
    draw_cfg(cfg)
    txt.write('}\n')
    txt.close()
示例#12
0
def analyze(cfg):
    entry = get_entry_node(cfg)
    global CT_nodes
    CT_nodes = set(cfg.nodes())
    while True:
        global post_n
        global post_n
        global visit
        global post_max
        global post_ctr
        post_n = {}  # map of Integer to Node
        post_i = {}  # map of Node to Integer
        visit = {}  # map of node to boolean
        post_max = 0
        post_ctr = 1
        old_size = len(cfg.nodes())
        dfs_postorder(cfg, entry)
        while len(cfg.nodes()) > 1 and post_ctr <= post_max:
            n = post_n[post_ctr]
            # locate an acycic region if present
            node_set = set()
            ntype = acyclic_region_type(cfg, n, node_set)
            if ntype is not None:
                p = reduce_nodes(cfg, ntype, node_set)
                if entry in node_set:
                    entry = p
            else:
                # locate a cyclic region, if present
                calculate_dominators(cfg, entry)
                reach_under = set()
                for m in cfg.nodes_iter():
                    if n in cfg.successors(m) and n in dominators[m]:
                        reach_under.add(m)
                m = get_closest(cfg, n, reach_under)
                ntype = None
                if m is not None:
                    reach_under = get_loop_nodes(cfg, n, m)
                    exit_edge = False
                    if len(reach_under) > 2:
                        to_remove = []
                        to_add = []
                        for r in reach_under:
                            if r == n or r == m:
                                continue
                            for s in cfg.successors(r):
                                # identify a Continue
                                if s == n:
                                    new = reduce_nodes(cfg, "Continue",
                                                       set([r]), s)
                                    to_remove.append(r)
                                    to_add.append(new)
                                    break
                                # Identify a Break
                                if s not in reach_under and s not in to_add:
                                    new = reduce_nodes(cfg, "Break", set([r]),
                                                       s)
                                    to_remove.append(r)
                                    to_add.append(new)
                                    break
                        for r in to_remove:
                            reach_under.remove(r)
                        for a in to_add:
                            reach_under.add(a)
                    #if not exit_edge:
                    ntype = cyclic_region_type(cfg, n, m, reach_under)
                if ntype is not None:
                    p = reduce_nodes(cfg, ntype, reach_under)
                    if entry in reach_under:
                        entry = p
                else:
                    post_ctr += 1
        new_size = len(cfg.nodes())
        if new_size == 1 or new_size == old_size:
            break
    return CT_nodes, CT_edges
示例#13
0
def acyclic_region_type(cfg, node, nset):
    # check for a Block containing node
    n = node
    p = True
    s = len(cfg.successors(n)) == 1
    while p and s:
        nset.add(n)
        n = cfg.successors(n)[0]
        p = len(cfg.predecessors(n)) == 1
        s = len(cfg.successors(n)) == 1
    if p and len(cfg.successors(n)) == 0:
        nset.add(n)
    n = node
    p = len(cfg.predecessors(n)) == 1
    s = len(cfg.successors(n)) < 2
    while p and s:
        nset.add(n)
        n = cfg.predecessors(n)[0]
        p = len(cfg.predecessors(n)) == 1
        s = len(cfg.successors(n)) == 1
    if s:
        nset.add(n)
    node = n
    if len(nset) >= 2:
        return "Block"
    elif len(cfg.successors(node)) == 2:
        succ0 = cfg.successors(node)[0]
        succ1 = cfg.successors(node)[1]
        # check for an IfThenElse
        if cfg.in_degree(succ0) == 1 and cfg.out_degree(
                succ0) == 1 and cfg.in_degree(succ1) == 1 and cfg.out_degree(
                    succ1) == 1:
            grandchild0 = cfg.successors(succ0)[0]
            grandchild1 = cfg.successors(succ1)[0]
            if grandchild0 == grandchild1:
                nset.add(node)
                nset.add(succ0)
                nset.add(succ1)
                return "IfThenElse"
        # check for an IfThen
        elif cfg.in_degree(succ0) == 1 and cfg.out_degree(
                succ0) == 1 and cfg.in_degree(succ1) == 2 and cfg.successors(
                    succ0)[0] == succ1:
            nset.add(node)
            nset.add(succ0)
            return "IfThen"
        elif cfg.in_degree(succ1) == 1 and cfg.out_degree(
                succ1) == 1 and cfg.in_degree(succ0) == 2 and cfg.successors(
                    succ1)[0] == succ0:
            nset.add(node)
            nset.add(succ1)
            return "IfThen"
        # other cases (IfThen, Switch) if . . .
    else:
        return None
示例#14
0
def dom_frontier(blocks):
    succ = {name: successors(block[-1]) for name, block in blocks.items()}
    dom = get_dom(succ, list(blocks.keys())[0])
    return dom_fronts(dom, succ)