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)
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()
"-": 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(["<<", ">>", "|", "&", "^", "~"])
} 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(["<<", ">>", "|", "&", "^", "~"])