def graphviz(tree,fp): fp.write('''strict digraph g { graph [rankdir="LR"]; node [shape=record]; ''') for u in node.postorder(tree): u._graphviz(fp) fp.write("}\n")
def graphviz(tree, fp): fp.write('''strict digraph g { graph [rankdir="LR"]; node [shape=record]; ''') for u in node.postorder(tree): u._graphviz(fp) fp.write("}\n")
def callgraph(func_list): """Build callgraph of func_list, ignoring built-in functions.""" G = nx.DiGraph() for func in func_list: G.add_node(func.head.ident.name) for func in func_list: assert isinstance(func, node.function) func_name = func.head.ident.name resolve.resolve(func) for s in node.postorder(func): if s.__class__ is node.funcall and s.func_expr.__class__ is node.ident and s.func_expr.name in G.nodes(): G.add_edge(func_name, s.func_expr.name) return G
def resolve(t,fp,func_name): fp.write("digraph %s {\n" % func_name) fp.write('graph [rankdir="LR"];\n') for u in node.postorder(t): if u.__class__ in (node.ident,node.param): fp.write("%s [label=%s_%s_%s];\n" % (u.lexpos,u.name,u.lineno,u.column)) if u.defs: for v in u.defs: fp.write("%s -> %s" % (u.lexpos,v.lexpos)) if u.lexpos < v.lexpos: fp.write('[color=red]') #else: # fp.write('[label=%s.%s]' % (v.lineno,v.column)) fp.write(';\n') fp.write("}\n")
def callgraph(func_list): """Build callgraph of func_list, ignoring built-in functions.""" G = nx.DiGraph() for func in func_list: G.add_node(func.head.ident.name) for func in func_list: assert isinstance(func, node.function) func_name = func.head.ident.name resolve.resolve(func) for s in node.postorder(func): if (s.__class__ is node.funcall and s.func_expr.__class__ is node.ident and s.func_expr.name in G.nodes()): G.add_edge(func_name, s.func_expr.name) return G
def graphviz(t,fp,func_name): fp.write("digraph %s {\n" % func_name) fp.write('graph [rankdir="LR"];\n') for u in node.postorder(t): if u.__class__ in (node.ident,node.param): fp.write("%s [label=%s_%s_%s];\n" % (u.lexpos,u.name,u.lineno,u.column)) if u.defs: for v in u.defs: fp.write("%s -> %s" % (u.lexpos,v.lexpos)) if u.lexpos < v.lexpos: fp.write('[color=red]') #else: # fp.write('[label=%s.%s]' % (v.lineno,v.column)) fp.write(';\n') fp.write("}\n")
def as_networkx(t): G = nx.DiGraph() for u in node.postorder(t): if u.__class__ in (node.ident,node.param): uu = "%s_%s_%s" % (u.name,u.lineno,u.column) #label = "%s\\n%s" % (uu, u.props if u.props else "") G.add_node(uu, ident=u) # label=label) if u.defs: for v in u.defs: vv = "%s_%s_%s" % (v.name,v.lineno,v.column) G.add_node(vv, ident=v) if u.lexpos < v.lexpos: G.add_edge(uu,vv,color="red") else: G.add_edge(uu,vv,color="black") return G
def resolve(t, symtab=None, fp=None, func_name=None): if symtab is None: symtab = {} do_resolve(t,symtab) G = as_networkx(t) #import pdb;pdb.set_trace() for n in G.nodes(): u = G.node[n]["ident"] if u.props: pass elif G.out_edges(n) and G.in_edges(n): u.props = "U" # upd #print u.name, u.lineno, u.column elif G.in_edges(n): u.props = "D" # def elif G.out_edges(n): u.props = "R" # ref else: u.props = "F" # ??? G.node[n]["label"] = "%s\\n%s" % (n, u.props) for u in node.postorder(t): #if u.__class__ is node.func_decl: # u.ident.name += "_" if u.__class__ is node.funcall: try: if u.func_expr.props in "UR": # upd,ref u.__class__ = node.arrayref #else: # u.func_expr.name += "_" except: pass for u in node.postorder(t): if u.__class__ in (node.arrayref,node.cellarrayref): for i,v in enumerate(u.args): if v.__class__ is node.expr and v.op == ":": v.op = "::" # for w in node.postorder(v): # if w.__class__ is node.expr and w.op == "end": # w.args[0] = u.func_expr # w.args[1] = node.number(i) for u in node.postorder(t): if u.__class__ is node.let: if (u.ret.__class__ is node.ident and u.args.__class__ is node.matrix): u.args = node.funcall(func_expr=node.ident("matlabarray"), args=node.expr_list([u.args])) H = nx.connected_components(G.to_undirected()) for i,component in enumerate(H): for nodename in component: if G.node[nodename]["ident"].props == "R": has_update = 1 break else: has_update = 0 if has_update: for nodename in component: G.node[nodename]["ident"].props += "S" # sparse #S = G.subgraph(nbunch) #print S.edges() return G
def rank(tree): @extend(node.number) def _rank(self): problem.addVariable(id(self),[0]) @extend(node.let) def _rank(self): if isinstance(self.ret,node.ident): # plain assignment -- not a field, lhs indexing vars = [id(self.ret), id(self.args)] try: problem.addVariables(vars,list(range(4))) problem.addConstraint(operator.__eq__,vars) except ValueError: pass else: # lhs indexing or field pass @extend(node.for_stmt) def _rank(self): vars = [id(self.ident), id(self.expr)] problem.addVariables(vars,list(range(4))) problem.addConstraint((lambda u,v: u+1==v),vars) @extend(node.if_stmt) def _rank(self): # could use operator.__not__ instead of lambda expression problem.addVariable(id(self.cond_expr),list(range(4))) problem.addConstraint(lambda t: t==0, [id(self.cond_expr)]) @extend(node.ident) def _rank(self): try: x = id(self) problem.addVariable(x,list(range(4))) for other in self.defs: y = id(other) try: problem.addVariable(y,list(range(4))) except ValueError: pass problem.addConstraint(operator.__eq__, [x,y]) except: print "Ignored ",self """ @extend(funcall) def rank(self,problem): if not isinstance(self.func_expr,ident): # In MATLAB, chaining subscripts, such as size(a)(1) # is not allowed, so only fields and dot expressions # go here. In Octave, chaining subscripts is allowed, # and such expressions go here. return try: if defs.degree(self.func_expr): # If a variable is defined, it is not a function, # except function handle usages, such as # foo=@size; foo(17) # which is not handled properly yet. x = id(self.func_expr) n = len(self.args) problem.addVariable(x,range(4)) problem.addConstraint((lambda u: u>=n),[x]) return except TypeError: # func_expr is unhashable # For example [10 20 30](2) return except KeyError: # See tests/clear_margins.m return assert getattr(self.func_expr,"name",None) # So func_expr is an undefined variable, and we understand # it's a function call -- either builtin or user-defined. name = self.func_expr.name # if name not in builtins: # # User-defined function # return # builtins[name](self,problem) # #@extend(expr) #def rank(self,problem): # try: # builtins[self.op](self,problem) # except: # pass """ problem = Problem(RecursiveBacktrackingSolver()) for v in node.postorder(tree): for u in v: try: u._rank() except AttributeError: pass s = problem.getSolution() if not s: print "No solutions" else: d = set() #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)): for k in node.postorder(tree): if isinstance(k,node.ident): print k.name,k.lineno, s.get(id(k),-1)
def do_rewrite(t): for u in node.postorder(t): try: u._rewrite() except: assert 0
def rank(tree): @extend(node.number) def _rank(self): problem.addVariable(id(self), [0]) @extend(node.let) def _rank(self): if isinstance(self.ret, node.ident): # plain assignment -- not a field, lhs indexing vars = [id(self.ret), id(self.args)] try: problem.addVariables(vars, range(4)) problem.addConstraint(operator.__eq__, vars) except ValueError: pass else: # lhs indexing or field pass @extend(node.for_stmt) def _rank(self): vars = [id(self.ident), id(self.expr)] problem.addVariables(vars, range(4)) problem.addConstraint((lambda u, v: u + 1 == v), vars) @extend(node.if_stmt) def _rank(self): # could use operator.__not__ instead of lambda expression problem.addVariable(id(self.cond_expr), range(4)) problem.addConstraint(lambda t: t == 0, [id(self.cond_expr)]) @extend(node.ident) def _rank(self): try: x = id(self) problem.addVariable(x, range(4)) for other in self.defs: y = id(other) try: problem.addVariable(y, range(4)) except ValueError: pass problem.addConstraint(operator.__eq__, [x, y]) except: print "Ignored ", self """ @extend(funcall) def rank(self,problem): if not isinstance(self.func_expr,ident): # In MATLAB, chaining subscripts, such as size(a)(1) # is not allowed, so only fields and dot expressions # go here. In Octave, chaining subscripts is allowed, # and such expressions go here. return try: if defs.degree(self.func_expr): # If a variable is defined, it is not a function, # except function handle usages, such as # foo=@size; foo(17) # which is not handled properly yet. x = id(self.func_expr) n = len(self.args) problem.addVariable(x,range(4)) problem.addConstraint((lambda u: u>=n),[x]) return except TypeError: # func_expr is unhashable # For example [10 20 30](2) return except KeyError: # See tests/clear_margins.m return assert getattr(self.func_expr,"name",None) # So func_expr is an undefined variable, and we understand # it's a function call -- either builtin or user-defined. name = self.func_expr.name # if name not in builtins: # # User-defined function # return # builtins[name](self,problem) # #@extend(expr) #def rank(self,problem): # try: # builtins[self.op](self,problem) # except: # pass """ problem = Problem(RecursiveBacktrackingSolver()) for v in node.postorder(tree): for u in v: try: u._rank() except AttributeError: pass s = problem.getSolution() if not s: print "No solutions" else: d = set() #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)): for k in node.postorder(tree): if isinstance(k, node.ident): print k.name, k.lineno, s.get(id(k), -1)