def _add_args(uses, newop, args): "Update uses when a new instruction is inserted" def add(arg): if isinstance(arg, (Op, FuncArg, Block)): uses[arg].add(newop) nestedmap(add, args)
def _del_args(uses, oldop, args): "Delete uses when an instruction is removed" seen = set() # Guard against duplicates in 'args' def remove(arg): if isinstance(arg, (FuncArg, Operation)) and arg not in seen: uses[arg].remove(oldop) seen.add(arg) nestedmap(remove, args)
def _del_args(uses, oldop, args): "Delete uses when an instruction is removed" seen = set() # Guard against duplicates in 'args' def remove(arg): if isinstance(arg, Operation) and arg not in seen: uses[arg].remove(oldop) seen.add(arg) nestedmap(remove, args)
def copy_function(func, temper=None, module=None): """Copy a Function. `temper` may be given to""" temper = temper or make_temper() f = Function(func.name, list(func.argnames), func.type, temper=temper) valuemap = {} lookup = partial(_lookup, module or func.module, f, valuemap) ### Construct new Blocks for block in func.blocks: new_block = Block(temper(block.name), f) valuemap[block] = new_block f.add_block(new_block) ### Construct new Operations for block in func.blocks: new_block = valuemap[block] for op in block.ops: new_op = Op(op.opcode, op.type, nestedmap(lookup, op.args), result=temper(op.result), parent=new_block) # assert new_op.result != op.result valuemap[op] = new_op new_block.append(new_op) return f
def replace_args(self, replacements): """ Replace arguments listed in the `replacements` dict. The replacement instructions must dominate this instruction. """ if replacements: newargs = nestedmap(lambda arg: replacements.get(arg, arg), self.args) self.set_args(newargs)
def operands(self): """ Operands to this operation, in the form of args with symbols and constants. >>> print Op("mul", Int32, [op_a, op_b]).operands ['a', 'b'] """ non_constants = (Block, Operation, FuncArg) result = lambda x: x.result if isinstance(x, non_constants) else x return nestedmap(result, self.args)
def copy_function(func, temper=None, module=None): """Copy a Function. `temper` may be given to""" temper = temper or make_temper() f = Function(func.name, list(func.argnames), func.type, temper=temper) valuemap = {} lookup = partial(_lookup, module or func.module, f, valuemap) ### Construct new Blocks for block in func.blocks: new_block = f.new_block(block.name) valuemap[block] = new_block ### Construct new Operations for block in func.blocks: new_block = valuemap[block] for op in block.ops: if op.opcode == 'phi': # Phi nodes may be circular, or may simply precede some of # their arguments args = [] else: args = nestedmap(lookup, op.args) new_op = Op(op.opcode, op.type, args, result=temper(op.result), parent=new_block) new_op.add_metadata(op.metadata) # assert new_op.result != op.result valuemap[op] = new_op new_block.append(new_op) for old_op in func.ops: if old_op.opcode == 'phi': new_op = valuemap[old_op] new_op.set_args(nestedmap(lookup, old_op.args)) return f, valuemap
def copy_function(func, temper=None, module=None): """Copy a Function. `temper` may be given to""" temper = temper or make_temper() f = Function(func.name, list(func.argnames), func.type, temper=temper) valuemap = {} lookup = partial(_lookup, module or func.module, f, valuemap) ### Construct new Blocks for block in func.blocks: new_block = Block(temper(block.name), f) valuemap[block] = new_block f.add_block(new_block) ### Construct new Operations for block in func.blocks: new_block = valuemap[block] for op in block.ops: if op.opcode == 'phi': # Phi nodes may be circular, or may simply precede some of # their arguments args = [] else: args = nestedmap(lookup, op.args) new_op = Op(op.opcode, op.type, args, result=temper(op.result), parent=new_block) new_op.add_metadata(op.metadata) # assert new_op.result != op.result valuemap[op] = new_op new_block.append(new_op) for old_op in func.ops: if old_op.opcode == 'phi': new_op = valuemap[old_op] new_op.set_args(nestedmap(lookup, old_op.args)) return f
def replace_uses(self, dst): """ Replace all uses of `self` with `dst`. This does not invalidate this Operation! """ src = self # Replace src with dst in use sites for use in set(self.function.uses[src]): def replace(op): if op == src: return dst return op newargs = nestedmap(replace, use.args) use.set_args(newargs)
def lltyping(func, env): """Annotate the function with the low-level representation types""" if not env['numba.state.opaque']: context = env['numba.typing.context'] resolve = partial(resolve_type, context) for arg in func.args: resolve(arg) for op in func.ops: if op.opcode == 'exc_catch': continue op.replace(resolve(op)) op.set_args(nestedmap(resolve, op.args)) restype = env['numba.typing.restype'] if conversion.byref(restype): ll_restype = ptypes.Void else: ll_restype = compiler.representation_type(restype) func.type = ptypes.Function(ll_restype, [arg.type for arg in func.args])
def lltyping(func, env): """Annotate the function with the low-level representation types""" if not env['flypy.state.opaque']: context = env['flypy.typing.context'] resolve = partial(resolve_type, context) for arg in func.args: resolve(arg) for op in func.ops: if op.opcode == 'exc_catch': continue op.replace(resolve(op)) op.set_args(nestedmap(resolve, op.args)) restype = env['flypy.typing.restype'] if conversion.byref(restype): ll_restype = ptypes.Void else: ll_restype = compiler.representation_type(restype) func.type = ptypes.Function(ll_restype, [arg.type for arg in func.args], False)
def load_args(self, op): if op.opcode == 'phi': # phis have cycles and values cannot be loaded in a single pass return () return nestedmap(self.load_op, op.args)
def substitute_args(op, oldargs, newargs): if oldargs != newargs: replacements = dict(zip(oldargs, newargs)) new_args = nestedmap(lambda x: replacements.get(x, x), op.args) op.set_args(new_args)
def collect_constants(op): constants = [] nestedmap(partial(_collect_constants, constants), op.args) return constants
def _format_args(args): return ", ".join(map(str, nestedmap(_format_arg, args)))