Пример #1
0
def opgrouper(visitor, prefix='op_'):
    """
    op_add, op_mul, ... -> op_binary
    """
    handlers = mergedicts(unop_handlers(visitor.op_unary, prefix),
                          binop_handlers(visitor.op_binary, prefix),
                          compare_handlers(visitor.op_compare, prefix))
    return combine(visitor, handlers)
Пример #2
0
def compute_dataflow(func, cfg, allocas, phis):
    """
    Compute the data flow by eliminating load and store ops (given allocas set)

    :param allocas: set of alloca variables to optimize ({Op})
    :param phis:    { φ Op -> alloca }
    """
    values = collections.defaultdict(dict) # {block : { stackvar : value }}

    # Track block values and delete load/store
    for block in func.blocks:
        # Copy predecessor outgoing values into current block values
        preds = cfg.predecessors(block)
        predvars = [values[pred] for pred in preds]
        blockvars = mergedicts(*predvars)

        for op in block.ops:
            if op.opcode == 'alloca' and op in allocas:
                # Initialize to Undefined
                blockvars[op] = Undef(op.type.base)
            elif op.opcode == 'load' and op.args[0] in allocas:
                # Replace load with value
                alloca, = op.args
                op.replace_uses(blockvars[alloca])
                op.delete()
            elif op.opcode == 'store' and op.args[1] in allocas:
                # Delete store and register result
                value, alloca = op.args
                blockvars[alloca] = value
                op.delete()
            elif op.opcode == 'phi' and op in phis:
                alloca = phis[op]
                blockvars[alloca] = op

        values[block] = blockvars

    # Update phis incoming values
    for phi in phis:
        preds = list(cfg.predecessors(phi.block))
        incoming = []
        for block in preds:
            alloca = phis[phi]
            value = values[block][alloca] # value leaving predecessor block
            incoming.append(value)

        phi.set_args([preds, incoming])

    # Remove allocas
    for alloca in allocas:
        alloca.delete()
Пример #3
0
def compute_dataflow(func, cfg, allocas, phis):
    """
    Compute the data flow by eliminating load and store ops (given allocas set)

    :param allocas: set of alloca variables to optimize ({Op})
    :param phis:    { φ Op -> alloca }
    """
    values = collections.defaultdict(dict)  # {block : { stackvar : value }}

    # Track block values and delete load/store
    for block in func.blocks:
        # Copy predecessor outgoing values into current block values
        preds = cfg.predecessors(block)
        predvars = [values[pred] for pred in preds]
        blockvars = mergedicts(*predvars)

        for op in block.ops:
            if op.opcode == 'alloca' and op in allocas:
                # Initialize to Undefined
                blockvars[op] = Undef(op.type.base)
            elif op.opcode == 'load' and op.args[0] in allocas:
                # Replace load with value
                alloca, = op.args
                op.replace_uses(blockvars[alloca])
                op.delete()
            elif op.opcode == 'store' and op.args[1] in allocas:
                # Delete store and register result
                value, alloca = op.args
                blockvars[alloca] = value
                op.delete()
            elif op.opcode == 'phi' and op in phis:
                alloca = phis[op]
                blockvars[alloca] = op

        values[block] = blockvars

    # Update phis incoming values
    for phi in phis:
        preds = list(cfg.predecessors(phi.block))
        incoming = []
        for block in preds:
            alloca = phis[phi]
            value = values[block][alloca]  # value leaving predecessor block
            incoming.append(value)

        phi.set_args([preds, incoming])

    # Remove allocas
    for alloca in allocas:
        alloca.delete()
Пример #4
0
    "-": ops.usub,
}

binary_defs = {
    "+":  ops.add,
    "-":  ops.sub,
    "*":  ops.mul,
    "/":  ops.div,
    "%":  ops.mod,
    "<<": ops.lshift,
    ">>": ops.rshift,
    "|":  ops.bitor,
    "&":  ops.bitand,
    "^":  ops.bitxor,
}

compare_defs = {
    "<":  ops.lt,
    "<=": ops.lte,
    ">":  ops.gt,
    ">=": ops.gte,
    "==": ops.eq,
    "!=": ops.noteq,
}

unary_opcodes = invert(unary_defs)
binary_opcodes = invert(binary_defs)
compare_opcodes = invert(compare_defs)

func2operator = mergedicts(invert(unary), invert(binary), invert(compare))
bitwise = set(["<<", ">>", "|", "&", "^", "~"])
Пример #5
0
}

binary_defs = {
    "+":  ops.add,
    "-":  ops.sub,
    "*":  ops.mul,
    "/":  ops.div,
    "%":  ops.mod,
    "<<": ops.lshift,
    ">>": ops.rshift,
    "|":  ops.bitor,
    "&":  ops.bitand,
    "^":  ops.bitxor,
}

compare_defs = {
    "<":  ops.lt,
    "<=": ops.le,
    ">":  ops.gt,
    ">=": ops.ge,
    "==": ops.eq,
    "!=": ops.ne,
}

unary_opcodes = invert(unary_defs)
binary_opcodes = invert(binary_defs)
compare_opcodes = invert(compare_defs)

opcode2operator = mergedicts(unary, binary, compare)
operator2opcode = mergedicts(invert(unary), invert(binary), invert(compare))
bitwise = set(["<<", ">>", "|", "&", "^", "~"])
Пример #6
0
}

binary_defs = {
    "+": ops.add,
    "-": ops.sub,
    "*": ops.mul,
    "/": ops.div,
    "%": ops.mod,
    "<<": ops.lshift,
    ">>": ops.rshift,
    "|": ops.bitor,
    "&": ops.bitand,
    "^": ops.bitxor,
}

compare_defs = {
    "<": ops.lt,
    "<=": ops.le,
    ">": ops.gt,
    ">=": ops.ge,
    "==": ops.eq,
    "!=": ops.ne,
}

unary_opcodes = invert(unary_defs)
binary_opcodes = invert(binary_defs)
compare_opcodes = invert(compare_defs)

opcode2operator = mergedicts(unary, binary, compare)
operator2opcode = mergedicts(invert(unary), invert(binary), invert(compare))
bitwise = set(["<<", ">>", "|", "&", "^", "~"])
Пример #7
0
    "-": ops.usub,
}

binary_defs = {
    "+": ops.add,
    "-": ops.sub,
    "*": ops.mul,
    "/": ops.div,
    "%": ops.mod,
    "<<": ops.lshift,
    ">>": ops.rshift,
    "|": ops.bitor,
    "&": ops.bitand,
    "^": ops.bitxor,
}

compare_defs = {
    "<": ops.lt,
    "<=": ops.lte,
    ">": ops.gt,
    ">=": ops.gte,
    "==": ops.eq,
    "!=": ops.noteq,
}

unary_opcodes = invert(unary_defs)
binary_opcodes = invert(binary_defs)
compare_opcodes = invert(compare_defs)

func2operator = mergedicts(invert(unary), invert(binary), invert(compare))
bitwise = set(["<<", ">>", "|", "&", "^", "~"])