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('}')
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, ))
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)
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
def func_from_ssa(func): blocks = block_map(form_blocks(func['instrs'])) add_entry(blocks) add_terminators(blocks) # Replace each phi-node. for block in blocks.values(): # Insert copies for each phi. for instr in block: if instr.get('op') == 'phi': dest = instr['dest'] type = instr['type'] for i, label in enumerate(instr['labels']): var = instr['args'][i] # Insert a copy in the predecessor block, before the # terminator. pred = blocks[label] pred.insert(-1, { 'op': 'id', 'type': type, 'args': [var], 'dest': dest, }) # Remove all phis. new_block = [i for i in block if i.get('op') != 'phi'] block[:] = new_block func['instrs'] = reassemble(blocks)
def liveness_analysis(func): # Form the CFG. blocks = cfg.block_map(form_blocks(func)) cfg.add_terminators(blocks) in_, out = df_worklist(blocks, ANALYSES['live']) constraints = [] for block in blocks: constraints += backward_use(out[block], blocks[block], in_[block]) return constraints
def to_ssa(json_input): inp = json.loads(json_input) for func in inp['functions']: blocks = block_map(form_blocks(func['instrs'])) add_entry(blocks) add_terminators(blocks) blocks = insert_phi(blocks) blocks = rename_vars(blocks) func['instrs'] = reassemble(blocks) return json.dumps(inp)
def run_df(bril, analysis): for func in bril['functions']: # Form the CFG. blocks = cfg.block_map(form_blocks(func['instrs'])) cfg.add_terminators(blocks) in_, out = df_worklist(blocks, analysis) for block in blocks: print('{}:'.format(block)) print(' in: ', fmt(in_[block])) print(' out:', fmt(out[block]))
def run_df(bril): for func in bril['functions']: # Form the CFG. blocks = cfg.block_map(form_blocks(func['instrs'])) cfg.add_terminators(blocks) df_worklist( blocks, bottom=set(), join=_union, transfer=lambda block, in_: gen(block).union(in_ - kill(block)), )
def run_df(bril, analysis): for func in bril['functions']: # Form the CFG. blocks = cfg.block_map(form_blocks(func['instrs'])) cfg.add_terminators(blocks) in_, out = df_worklist(blocks, analysis) constraints = [] for block in blocks: #print('{}:'.format(block)) #print(' in: ', fmt(in_[block])) #print(' out:', fmt(out[block])) constraints += backward_use(out[block], blocks[block], in_[block]) return constraints
def to_ssa(bril): for func in bril['functions']: blocks = block_map(form_blocks(func['instrs'])) add_terminators(blocks) succ = { name: block_successors(block) for name, block in blocks.items() } # dom maps each node to the nodes that dominate it dom = get_dom(succ, list(blocks.keys())[0]) frontiers = get_frontiers(blocks, dom) insert_phi_nodes(blocks, frontiers)
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, ))
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)
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, ))
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()
def tail_merging(blocks): while(tail_merging_once(blocks)): pass # print("=======================") # for block in blocks: # print('{}:'.format(block)) # print('{}:'.format(blocks[block])) return blocks if __name__ == '__main__': bril = json.load(sys.stdin) for func in bril['functions']: # Form the CFG. blocks = cfg.block_map(form_blocks(func['instrs'])) cfg.add_terminators(blocks) # for block in blocks: # print('{}:'.format(block)) # print('{}:'.format(blocks[block])) # br_removal(blocks) # print("================after br_removal ==================") # for block in blocks: # print('{}:'.format(block)) # print('{}:'.format(blocks[block])) # unreachable_removal(blocks) # print("================after unreachable_removal ==================")