def visit_While(self, node): md.visit(self, node) self.visit(node.test) self.visit_loop(node.body) map(self.visit, node.orelse)
def visit_TryExcept(self, node): md.visit(self, node) # body all_node = dict() for stmt in node.body: self.visit(stmt) for k, i in self.current_node.iteritems(): if k not in all_node: all_node[k] = i else: all_node[k].update(i) no_except = self.current_node # except for ex in node.handlers: self.current_node = dict(all_node) self.visit(ex) # merge result self.merge_dict_set(no_except, self.current_node) self.current_node = no_except if node.orelse: err = ("orelse should have been removed in previous passes") raise PythranSyntaxError(err, node)
def visit_Assign(self, node): # order matter as an assignation # is evaluated before being assigned md.visit(self, node) self.visit(node.value) for target in node.targets: self.visit(target)
def visit_Assign(self, node): ''' Assignment creates aliasing between lhs and rhs >>> from pythran import passmanager >>> pm = passmanager.PassManager('demo') >>> module = ast.parse('def foo(a): c = a ; d = e = c ; {c, d, e}') >>> result = pm.gather(Aliases, module) >>> Aliases.dump(result, filter=ast.Set) {c, d, e} => ['|a|', '|a|', '|a|'] Everyone points to the formal parameter 'a' \o/ ''' md.visit(self, node) value_aliases = self.visit(node.value) for t in node.targets: if isinstance(t, ast.Name): self.aliases[t.id] = set(value_aliases) or {t} for alias in list(value_aliases): if isinstance(alias, ast.Name): a_id = alias.id self.aliases[a_id] = self.aliases[a_id].union((t,)) self.add(t, self.aliases[t.id]) else: self.visit(t)
def visit_Assign(self, node): md.visit(self, node) # in assignation, left expression is compute before the assignation # to the right expression self.visit(node.value) for n in node.targets: self.visit(n)
def visit_IfExp(self, node): md.visit(self, node) swap = False self.visit(node.test) # if an identifier is first used in orelse and we are in a loop, # we swap orelse and body undef = self.passmanager.gather(ImportedIds, node.body, self.ctx) if undef and self.in_loop: node.body, node.orelse = node.orelse, node.body swap = True # body old_node = {i: set(j) for i, j in self.current_node.iteritems()} self.visit(node.body) # orelse new_node = self.current_node self.current_node = old_node self.visit(node.orelse) if swap: node.body, node.orelse = node.orelse, node.body # merge result self.merge_dict_set(self.current_node, new_node)
def visit_Assign(self, node): r''' Assignment creates aliasing between lhs and rhs >>> from pythran import passmanager >>> pm = passmanager.PassManager('demo') >>> module = ast.parse('def foo(a): c = a ; d = e = c ; {c, d, e}') >>> result = pm.gather(Aliases, module) >>> Aliases.dump(result, filter=ast.Set) {c, d, e} => ['|a|'] Everyone points to the formal parameter 'a' \o/ ''' md.visit(self, node) value_aliases = self.visit(node.value) for t in node.targets: if isinstance(t, ast.Name): self.aliases[t.id] = set(value_aliases) or {t} for alias in list(value_aliases): if isinstance(alias, ast.Name): a_id = alias.id self.aliases[a_id] = self.aliases[a_id].union((t,)) self.add(t, self.aliases[t.id]) else: self.visit(t)
def visit_For(self, node): self.expr_parent = node self.result[node] = self.locals.copy() md.visit(self, node) self.visit(node.iter) self.locals.add(node.target.id) map(self.visit, node.body) map(self.visit, node.orelse)
def visit_Assign(self, node): self.expr_parent = node self.result[node] = self.locals.copy() md.visit(self, node) self.visit(node.value) self.locals.update(t.id for t in node.targets if isinstance(t, ast.Name)) map(self.visit, node.targets)
def visit_While(self, node): md.visit(self, node) self.visit(node.test) self.visit_loop(node.body) for stmt in node.orelse: self.visit(stmt)
def visit_While(self, node): md.visit(self, node) self.visit(node.test) self.in_loop = True map(self.visit, node.body) self.in_loop = False map(self.visit, node.orelse)
def visit_For(self, node): self.expr_parent = node self.result[node] = self.locals.copy() md.visit(self, node) self.visit(node.iter) self.locals.add(node.target.id) for stmt in node.body: self.visit(stmt) for stmt in node.orelse: self.visit(stmt)
def visit_Assign(self, node): md.visit(self, node) value_aliases = self.visit(node.value) for t in node.targets: if isinstance(t, ast.Name): self.aliases[t.id] = value_aliases or {t} for alias in list(value_aliases): if isinstance(alias, ast.Name): self.aliases[alias.id].add(t) else: self.visit(t)
def visit_Call(self, node): """ Compute use of variables in a function call. Each arg is use once and function name too. Information about modified arguments is forwarded to func_args_lazyness. """ md.visit(self, node) map(self.visit, node.args) self.func_args_lazyness(node.func, node.args, node) self.visit(node.func)
def visit_For(self, node): md.visit(self, node) ids = self.passmanager.gather(Identifiers, node.iter, self.ctx) if isinstance(node.target, ast.Name): self.assign_to(node.target, ids, node.iter) self.result[node.target.id] = LazynessAnalysis.INF else: err = "Assignation in for loop not to a Name" raise PythranSyntaxError(err, node) self.visit_loop(node.body) map(self.visit, node.orelse)
def visit_AugAssign(self, node): md.visit(self, node) self.visit(node.value) self.visit(node.target) var = node.target while isinstance(var, ast.Subscript): var = var.value if isinstance(var, ast.Name): var = var.id else: err = "AugAssign can't be used on {0}" raise PythranSyntaxError(err.format(var), node) last_node = self.current_node[var].pop() self.result[var].node[last_node]['action'] = "UD" self.current_node[var] = set([last_node])
def visit_AugAssign(self, node): md.visit(self, node) # augassigned variable can't be lazy self.visit(node.value) if isinstance(node.target, ast.Name): # variable is modified so other variables that use it dies self.modify(node.target.id) # and this variable can't be lazy self.result[node.target.id] = LazynessAnalysis.INF elif isinstance(node.target, ast.Subscript) or isattr(node.target): var_name = get_variable(node.target) # variable is modified so other variables that use it dies self.modify(var_name.id) # and this variable can't be lazy self.result[var_name.id] = LazynessAnalysis.INF else: raise PythranSyntaxError("AugAssign to unknown node", node)
def visit_Assign(self, node): md.visit(self, node) self.visit(node.value) ids = self.passmanager.gather(Identifiers, node.value, self.ctx) for target in node.targets: if isinstance(target, ast.Name): self.assign_to(target, ids, node.value) if node.value not in self.pure_expressions: self.result[target.id] = LazynessAnalysis.INF elif isinstance(target, ast.Subscript): # if we modify just a part of a variable, it can't be lazy var_name = get_variable(target) if isinstance(var_name, ast.Name): # variable is modified so other variables that use it dies self.modify(var_name.id, node.value) # and this variable can't be lazy self.result[var_name.id] = LazynessAnalysis.INF else: raise PythranSyntaxError("Assign to unknown node", node)
def visit_If(self, node): md.visit(self, node) self.visit(node.test) old_count = dict(self.name_count) old_dead = set(self.dead) old_deps = {a: set(b) for a, b in self.use.items()} # wrap body in a list if we come from an ifExp body = node.body if isinstance(node.body, list) else [node.body] for stmt in body: self.visit(stmt) mid_count = self.name_count mid_dead = self.dead mid_deps = self.use self.name_count = old_count self.dead = old_dead self.use = old_deps # wrap orelse in a list if we come from an ifExp orelse = (node.orelse if isinstance(node.orelse, list) else [node.orelse]) for stmt in orelse: self.visit(stmt) # merge use variable for key in self.use: if key in mid_deps: self.use[key].update(mid_deps[key]) for key in mid_deps: if key not in self.use: self.use[key] = set(mid_deps[key]) # value is the worse case of both branches names = set(self.name_count.keys()).union(mid_count.keys()) for name in names: val_body = mid_count.get(name, 0) val_else = self.name_count.get(name, 0) self.name_count[name] = max(val_body, val_else) # dead var are still dead self.dead.update(mid_dead)
def visit_If(self, node): ''' After an if statement, the values from both branches are merged, potentially creating more aliasing: >>> from pythran import passmanager >>> pm = passmanager.PassManager('demo') >>> fun = """ ... def foo(a, b): ... if a: c=a ... else: c=b ... return {c}""" >>> module = ast.parse(fun) >>> result = pm.gather(Aliases, module) >>> Aliases.dump(result, filter=ast.Set) {c} => ['|a|', '|b|'] ''' md.visit(self, node) self.visit(node.test) false_aliases = self.aliases.copy() try: # first try the true branch for stmt in node.body: self.visit(stmt) true_aliases, self.aliases = self.aliases, false_aliases except PythranSyntaxError: # it failed, try the false branch for stmt in node.orelse: self.visit(stmt) raise # but still throw the exception, maybe we are in a For try: # then try the false branch for stmt in node.orelse: self.visit(stmt) except PythranSyntaxError: # it failed # we still get some info from the true branch, validate them self.aliases = true_aliases raise # and let other visit_ handle the issue for k, v in true_aliases.items(): if k in self.aliases: self.aliases[k] = self.aliases[k].union(v) else: assert isinstance(v, (frozenset, set)) self.aliases[k] = v
def visit_While(self, node): md.visit(self, node) prev_node = {i: set(j) for i, j in self.current_node.iteritems()} self.visit(node.test) # body self.in_loop = True old_node = {i: set(j) for i, j in self.current_node.iteritems()} map(self.visit, node.body) self.add_loop_edges(prev_node) self.in_loop = False # orelse new_node = self.current_node self.merge_dict_set(self.current_node, old_node) map(self.visit, node.orelse) # merge result self.merge_dict_set(self.current_node, new_node) self.merge_dict_set(self.current_node, self.break_) self.break_ = dict()
def visit_For(self, node): md.visit(self, node) self.visit(node.iter) # body self.in_loop = True old_node = {i: set(j) for i, j in self.current_node.items()} self.visit(node.target) list(map(self.visit, node.body)) self.add_loop_edges(old_node) self.in_loop = False # orelse new_node = self.current_node self.merge_dict_set(self.current_node, old_node) list(map(self.visit, node.orelse)) # merge result self.merge_dict_set(self.current_node, new_node) self.merge_dict_set(self.current_node, self.break_) self.break_ = dict()
def visit_If(self, node): md.visit(self, node) self.visit(node.test) old_count = dict(self.name_count) old_dead = set(self.dead) old_deps = {a: set(b) for a, b in self.use.iteritems()} if isinstance(node.body, list): map(self.visit, node.body) else: self.visit(node.body) mid_count = self.name_count mid_dead = self.dead mid_deps = self.use self.name_count = old_count self.dead = old_dead self.use = old_deps if isinstance(node.orelse, list): map(self.visit, node.orelse) else: self.visit(node.orelse) # merge use variable for key in self.use: if key in mid_deps: self.use[key].update(mid_deps[key]) for key in mid_deps: if key not in self.use: self.use[key] = set(mid_deps[key]) # value is the worse case of both branches names = set(self.name_count.keys() + mid_count.keys()) for name in names: val_body = mid_count.get(name, 0) val_else = self.name_count.get(name, 0) self.name_count[name] = max(val_body, val_else) # dead var are still dead self.dead.update(mid_dead)
def visit_If(self, node): md.visit(self, node) self.visit(node.test) false_aliases = {k: v.copy() for k, v in self.aliases.iteritems()} try: # first try the true branch map(self.visit, node.body) true_aliases, self.aliases = self.aliases, false_aliases except PythranSyntaxError: # it failed, try the false branch map(self.visit, node.orelse) raise # but still throw the exception, maybe we are in a For try: # then try the false branch map(self.visit, node.orelse) except PythranSyntaxError: # it failed # we still get some info from the true branch, validate them self.aliases = true_aliases raise # and let other visit_ handle the issue for k, v in true_aliases.iteritems(): if k in self.aliases: self.aliases[k].update(v) else: assert isinstance(v, set) self.aliases[k] = v
def visit_If(self, node): md.visit(self, node) self.visit(node.test) false_aliases = {k: v.copy() for k, v in self.aliases.items()} try: # first try the true branch map(self.visit, node.body) true_aliases, self.aliases = self.aliases, false_aliases except PythranSyntaxError: # it failed, try the false branch map(self.visit, node.orelse) raise # but still throw the exception, maybe we are in a For try: # then try the false branch map(self.visit, node.orelse) except PythranSyntaxError: # it failed # we still get some info from the true branch, validate them self.aliases = true_aliases raise # and let other visit_ handle the issue for k, v in true_aliases.items(): if k in self.aliases: self.aliases[k].update(v) else: assert isinstance(v, set) self.aliases[k] = v
def visit_FunctionDef(self, node): # top-level OMP statements attached to that function md.visit(self, node) # special case for nested functions if self.nesting: self.locals.add(node.name) self.nesting += 1 self.expr_parent = node self.result[node] = self.locals.copy() parent_locals = self.locals.copy() for default in node.args.defaults: self.visit(default) for arg in node.args.args: if arg.annotation: self.visit(arg.annotation) if node.returns: self.visit(node.returns) self.locals.update(arg.id for arg in node.args.args) for stmt in node.body: self.visit(stmt) self.locals = parent_locals self.nesting -= 1
def visit_Try(self, node): md.visit(self, node) # body all_node = dict() for stmt in node.body + node.orelse: self.visit(stmt) for k, i in self.current_node.items(): if k not in all_node: all_node[k] = i else: all_node[k].update(i) no_except = self.current_node # except for ex in node.handlers: self.current_node = dict(all_node) self.visit(ex) # merge result self.merge_dict_set(no_except, self.current_node) self.current_node = no_except
def visit(self, node): # be aware of metadata md.visit(self, node) return super(ExtendedDefUseChains, self).visit(node)
def visit_If(self, node): ''' After an if statement, the values from both branches are merged, potentially creating more aliasing: >>> from pythran import passmanager >>> pm = passmanager.PassManager('demo') >>> fun = """ ... def foo(a, b): ... if a: c=a ... else: c=b ... return {c}""" >>> module = ast.parse(fun) >>> result = pm.gather(Aliases, module) >>> Aliases.dump(result, filter=ast.Set) {c} => ['|a|', '|b|'] ''' md.visit(self, node) self.visit(node.test) true_aliases = false_aliases = None # first try the true branch try: tmp = self.aliases.copy() for stmt in node.body: self.visit(stmt) true_aliases = self.aliases self.aliases = tmp except PythranSyntaxError: pass # then try the false branch try: for stmt in node.orelse: self.visit(stmt) false_aliases = self.aliases except PythranSyntaxError: pass if true_aliases and not false_aliases: self.aliases = true_aliases try: for stmt in node.orelse: self.visit(stmt) false_aliases = self.aliases except PythranSyntaxError: pass if false_aliases and not true_aliases: self.aliases = false_aliases try: for stmt in node.body: self.visit(stmt) true_aliases = self.aliases except PythranSyntaxError: pass # merge the results from true and false branches if false_aliases and true_aliases: for k, v in true_aliases.items(): if k in self.aliases: self.aliases[k] = self.aliases[k].union(v) else: assert isinstance(v, (frozenset, set)) self.aliases[k] = v elif true_aliases: self.aliases = true_aliases
def visit_Continue(self, node): md.visit(self, node) self.merge_dict_set(self.continue_, self.current_node)
def visit(self, node): metadata.visit(self, node) return super(CxxFunction, self).visit(node)
def visit_Assign(self, node): #order matter as an assignation #is evaluted before being assigned md.visit(self, node) self.visit(node.value) map(self.visit, node.targets)
def visit_Break(self, node): md.visit(self, node) self.merge_dict_set(self.break_, self.current_node)
def visit_Call(self, node): md.visit(self, node) map(self.visit, node.args) self.func_args_lazyness(node.func, node.args, node)
def visit_Assign(self, node): # order matter as an assignation # is evaluted before being assigned md.visit(self, node) self.visit(node.value) map(self.visit, node.targets)