Example #1
0
def clean_cfg(blocks):
    changed = True
    while changed:
        preds, succs = cfg.edges(blocks)
        visited = dict.fromkeys(blocks.keys(),False)
        changed = _clean_cfg(blocks.keys()[0], blocks, preds, succs, visited)
        # for block in blocks:
        #     print('{}:'.format(block))
        #     print('{}:'.format(blocks[block]))
    return blocks
Example #2
0
def br_removal(blocks):
    in_, out = df_worklist(blocks, ANALYSES['cprop'])
    # overwirte blocks
    preds, succs = cfg.edges(blocks)
    for index, block in blocks.items():
        vals = out[index]
        if block[-1] is not None and block[-1]['op'] == 'br':
            guard = block[-1]['args'][0]
            if guard in vals:
                block[-1]['op'] = 'jmp'
                if vals[guard]:
                    block[-1]['args'] = [block[-1]['args'][1]]
                else:
                    block[-1]['args'] = [block[-1]['args'][2]]
    return blocks
Example #3
0
def unreachable_removal(blocks):
    preds, succs = cfg.edges(blocks)
    reachable = dict.fromkeys(blocks.keys(),False)
    reachable[blocks.keys()[0]] = True
    stack = [blocks.keys()[0]]
    while(len(stack) != 0):
        b = stack.pop() 
        for s in succs[b]:
            if not reachable[s]:
                reachable[s] = True
                stack.append(s)

    for b, r in reachable.items():
        if not r :
            del blocks[b]

    return blocks
Example #4
0
def cfg_to_code(blocks, f_name):
    preds, succs = cfg.edges(blocks)
    instrs = []
    for name, block in blocks.items():
        if len(instrs) != 0 and instrs[-1]['op'] == 'jmp' and instrs[-1][
                'args'][0] == name:
            instrs = instrs[:-1]
            if len(preds[name]) == 1:
                # this label is only for the fall through
                instrs += block
                continue
        if len(preds[name]) != 0:
            instrs += [{"label": name}]
        instrs += block
    data = {'functions': [{"name": f_name}]}
    data['functions'][0]['instrs'] = instrs
    json_data = json.dumps(data, indent=2, sort_keys=True)
    return json_data
Example #5
0
def df_worklist(blocks, analysis):
    """The worklist algorithm for iterating a data flow analysis to a
    fixed point.
    """
    preds, succs = cfg.edges(blocks)

    # Switch between directions.
    if analysis.forward:
        first_block = list(blocks.keys())[0]  # Entry.
        in_edges = preds
        out_edges = succs
    else:
        first_block = list(blocks.keys())[-1]  # Exit.
        in_edges = succs
        out_edges = preds

    # Initialize.
    in_ = {first_block: analysis.init}
    out = {node: analysis.init for node in blocks}

    # Iterate.
    worklist = list(blocks.keys())
    while worklist:
        node = worklist.pop(0)

        inval = analysis.merge(out[n] for n in in_edges[node])
        in_[node] = inval

        outval = analysis.transfer(blocks[node], inval)

        if outval != out[node]:
            out[node] = outval
            worklist += out_edges[node]

    if analysis.forward:
        return in_, out
    else:
        return out, in_
Example #6
0
File: df.py Project: sa2257/vril
def df_worklist(blocks, bottom, join, transfer):
    preds, succs = cfg.edges(blocks)
    entry = list(blocks.keys())[0]

    # Initialize.
    invals = {entry: bottom}
    outvals = {node: bottom for node in blocks}
    worklist = list(blocks.keys())

    # Iterate.
    while worklist:
        node = worklist.pop(0)

        inval = join(outvals[n] for n in preds[node])
        invals[node] = inval

        outval = transfer(blocks[node], inval)

        if outval != outvals[node]:
            outvals[node] = outval
            worklist += succs[node]

    print(invals)
    print(outvals)
Example #7
0
def tail_merging_once(blocks):
    preds, succs = cfg.edges(blocks)
   
    bns = list(blocks.keys())
    for block in bns:
        count = {}
        # merge two preds
       
        for p in preds[block]:
            instr = blocks[p][-1]
            if instr is not None and instr['op'] == 'jmp':
                k = canonicalize(instr) 
                if k not in count:
                    count[k] = p
                else:
                    # find two blocks can be merged
                    b1 = blocks[count[k]]
                    b2 = blocks[p]
                    name, l = merge(b1, b2, list(blocks.keys()), from_start = False)
                    if l == 1:
                        continue
                    
                    if l == min(len(b1),len(b2)):
                        if len(b1) == len(b2):
                            replace_target(preds[count[k]] +  preds[p], blocks, [count[k], p], name)
                            del blocks[count[k]]
                            del blocks[p]
                            return True
                        if len(b1) < len(b2):
                            small_block = count[k]
                            large_block = p
                        else:   
                            small_block = p
                            large_block = count[k]

                        blocks[large_block] = blocks[large_block][:len(blocks[large_block]) - l]
                        jmp = {'op': 'jmp', "args": [small_block]} 
                        blocks[large_block].append(jmp)

                    else:
                        jmp = {'op': 'jmp', "args": [name]} 
                        new_block = b1[len(b1) - l:]
                        blocks[name] = new_block
                        blocks[count[k]] = b1[:len(b1) - l]
                        blocks[count[k]].append(jmp)
                        blocks[p] = b2[:len(b2) - l]
                        blocks[p].append(jmp)
                    return True                   
                    

        # merge two succs
        if blocks[block][-1] is not None and blocks[block][-1]['op'] == 'br':
            args = blocks[block][-1]['args']
            b1 = blocks[args[1]]
            b2 = blocks[args[2]]
            name, l = merge(b1, b2, list(blocks.keys()),from_start = True)
            if l > 0:  
                if l == len(b1):
                    # cannot have jmp in middle of block
                    # so this is the only case such that a block is entirely duplicated
                    jmp = {'op': 'jmp', "args": [args[1]]}
                    blocks[block] = blocks[block][:-1]
                    blocks[block].append(jmp)
                    replace_target(preds[args[2]], blocks, [args[2]], args[1])
                    del blocks[args[2]]
                else:
                    jmp = {'op': 'jmp', "args": [name]}
                    br = blocks[block][-1]
                    blocks[block] = blocks[block][:-1]
                    blocks[block].append(jmp)
                    replace_target(preds[args[1]] +  preds[args[2]], blocks, args[1:3], name)
                    blocks[name] = b1[:l]
                    blocks[args[1]] = b1[l:]
                    blocks[args[2]] = b2[l:]
                    blocks[name].append(br)
                return True
    

    return False