[pypy-svn] rev 2062 - in pypy/trunk/src/pypy/translator: test tool
hpk at codespeak.net
hpk at codespeak.net
Sat Oct 25 21:41:59 CEST 2003
Author: hpk
Date: Sat Oct 25 21:41:58 2003
New Revision: 2062
Added:
pypy/trunk/src/pypy/translator/tool/autopath.py (props changed)
- copied unchanged from rev 2050, pypy/trunk/src/pypy/tool/autopath.py
Modified:
pypy/trunk/src/pypy/translator/test/test_pyrextrans.py
pypy/trunk/src/pypy/translator/test/test_typedpyrex.py
pypy/trunk/src/pypy/translator/tool/make_dot.py
Log:
- rewrote make_dot with the new model.traverse approach
- enabled dot everywhere :-)
Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_pyrextrans.py (original)
+++ pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Sat Oct 25 21:41:58 2003
@@ -6,10 +6,10 @@
from pypy.translator.tool.buildpyxmodule import make_module_from_pyxstring
-make_dot = False
+make_dot = True
if make_dot:
- from pypy.translator.test.make_dot import make_dot
+ from pypy.translator.tool.make_dot import make_dot
else:
def make_dot(*args): pass
Modified: pypy/trunk/src/pypy/translator/test/test_typedpyrex.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_typedpyrex.py (original)
+++ pypy/trunk/src/pypy/translator/test/test_typedpyrex.py Sat Oct 25 21:41:58 2003
@@ -6,7 +6,7 @@
from pypy.translator.tool.buildpyxmodule import make_module_from_pyxstring
-make_dot = False
+make_dot = True
if make_dot:
from pypy.translator.test.make_dot import make_dot
Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py
==============================================================================
--- pypy/trunk/src/pypy/translator/tool/make_dot.py (original)
+++ pypy/trunk/src/pypy/translator/tool/make_dot.py Sat Oct 25 21:41:58 2003
@@ -3,129 +3,23 @@
"""
"""
-import autopath
-from pypy.translator.flowmodel import *
-import os
+import autopath, os
+from pypy.objspace.flow.model import *
+from pypy.objspace.flow import Space
+from pypy.tool.udir import udir
debug = 0
-
-counters = {}
-class Node:
- allnodes = []
- def __init__(self, obj):
- self.obj = obj
- self.allnodes.append(self)
- self.edges = []
- self.make_name()
- self.data = []
-
- def make_name(self):
- cls = type(self)
- num = counters.setdefault(cls, 0)
- counters[cls] += 1
- self.name = '%s%d' % (self.__class__.__name__, num)
-
- def addedge(self, othernode, name=None):
- """ append edge (if not already in the list)
- return true if it really was added
- """
- if othernode not in self.edges:
- self.edges.append((othernode, name))
- return 1
-
- def descr_edges(self):
- l = []
- style = self.linestyle()
- for node,name in self.edges:
- if node in self.allnodes:
- if name == 'prevblock':
- l.append('edge [style=dotted, weight=0, label="%s"]; %s -> %s;' % (name, self, node))
- else:
- l.append('edge [style=%s, label="%s"]; %s -> %s;' % (style, name, self, node))
- else:
- pass
- return "\n".join(l)
-
- def linestyle(self):
- return "solid"
-
- def get_data(self):
- l = self.data[:]
- l.insert(0, "%s" % self.obj.__class__.__name__)
- return "\\n".join(l)
-
- def __str__(self):
- return self.name
-
-class NodeFunctionGraph(Node):
- def descr_node(self):
- """ obj attrs startblock, functionname """
- name = self.name
- data = self.get_data()
- return '%(name)s [shape=box, label="%(data)s"];' % locals()
-
- def make_name(self):
- self.name = self.obj.functionname
-
-class NodeBasicBlock(Node):
- def descr_node(self):
- """ condition, ifbranch, elsebranch """
- name = self.name
- data = self.get_data()
- #content = "\\n".join([name] + map(repr,self.obj.operations)) + "\\n"+data
- return '%(name)s [shape=box, label="%(data)s"];' % locals()
-
-class NodeBranch(Node):
- def descr_node(self):
- """ args, target """
- name = self.name
- data = self.get_data()
- return '%(name)s [shape=diamond, label="%(data)s"];' % locals()
-
-class NodeConditionalBranch(Node):
- def descr_node(self):
- """ args, target """
- name = self.name
- data = self.get_data()
- return '%(name)s [shape=diamond, label="%(data)s"];' % locals()
-
- def linestyle(self):
- return 'dashed'
-
-class NodeEndBranch(Node):
- def descr_node(self):
- """ args, target """
- name = self.name
- data = self.get_data()
- return '%(name)s [shape=circle, label="%(data)s"];' % locals()
-
-def flatten(*args):
- for arg in args:
- try:
- for atom in apply(flatten,arg):
- yield atom
- except: yield arg
-
-
class DotGen:
def __init__(self):
self.nodes = {}
self.counters = {}
- def get_source(self, fun):
- self.traverse(fun)
- l = []
- for node in self.nodes.values():
- if hasattr(node, 'source'):
- l.insert(0, node.descr_node())
- l.insert(0, node.descr_edges())
- else:
- l.append(node.descr_node())
- l.append(node.descr_edges())
-
- content = "\n".join(l)
-
+ def get_source(self, funcgraph):
+ self.blocks = {}
+ self.lines = []
+ traverse(self, funcgraph)
+ content = "\n".join(self.lines)
return """
digraph test {
node [fontname=Times];
@@ -133,102 +27,101 @@
%(content)s
}""" % locals()
- def get_node_class(self, cls):
- g = globals()
- #print cls.__name__
- nodeclass = g.get('Node%s' % cls.__name__, None)
- if nodeclass:
- return nodeclass
-
- for base in cls.__bases__:
- nodeclass = self.get_node_class(base)
- if nodeclass:
- return nodeclass
-
- def makenode(self, obj):
+ def blockname(self, block):
+ i = id(block)
try:
- return self.nodes[obj]
+ return self.blocks[i]
except KeyError:
- pass
- if not hasattr(obj, '__class__'):
- return
- cls = self.get_node_class(obj.__class__)
- if cls is not None:
- node = cls(obj)
- self.nodes[obj] = node
- return node
+ self.blocks[i] = name = "block%d" % len(self.blocks)
+ return name
- def traverse(self, obj, objname=None):
- try:
- return self.nodes[obj]
- except KeyError:
- pass
- except TypeError:
- return
- node = self.makenode(obj)
- if node:
- self.nodes[obj] = node
- for name, attr in obj.__dict__.items():
- ##XXX it makes the graph not very readeable
- if name == "framestate":
- continue
- trynode = self.traverse(attr, name)
- if trynode:
- node.addedge(trynode, name)
- else:
- if name == 'source' and type(attr) is str:
- attr = "\\l".join(attr.split('\n'))
- node.data.append('\\l%s' % attr.replace('"', '\\"'))
- else:
- node.data.append("%s=%s" % (name, repr(attr).replace('"', '\\"')))
- #print "unknown attribute", name, item
- return node
- elif debug:
- print "unknown obj", obj
+ def emit(self, line):
+ self.lines.append(line)
+
+ def emit_edge(self, name1, name2, label="", style="dashed", **kw):
+ d = locals()
+ d.update(kw)
+ self.emit('edge [style="%(style)s", dir="forward", weight=0, label="%(label)s"];' % d)
+ self.emit('%(name1)s -> %(name2)s;' % d)
+
+ def emit_node(self, name, shape, label, **kw):
+ d = locals()
+ d.update(kw)
+ self.emit('%(name)s [shape=%(shape)s, label="%(label)s"];' % d)
+
+ def visit(self, obj):
+ # ignore for now
+ return
+
+ def visit_FunctionGraph(self, funcgraph):
+ name = funcgraph.name
+ data = name
+ self.emit('%(name)s [shape=circle, label="%(data)s"];' % locals())
+ self.emit_edge(name, self.blockname(funcgraph.startblock), 'startblock')
+
+ def visit_Block(self, block):
+ name = self.blockname(block)
+ lines = []
+
+ lines.extend(map(repr, block.operations))
+ lines.append("")
+
+ numblocks = len(block.exits)
+
+ if not numblocks:
+ shape = "circle"
+ elif numblocks == 1:
+ shape = "box"
+ else:
+ lines.append("exitswitch: %s" % block.exitswitch)
+ shape = "octagon"
+
+ iargs = " ".join(map(repr, block.inputargs))
+ data = "%s(%s)\\ninputargs: %s\\n\\n" % (name, block.__class__.__name__, iargs)
+ data = data + "\l".join(lines)
+ self.emit_node(name, shape, data)
+
+ if numblocks == 1:
+ name2 = self.blockname(block.exits[0].target)
+ label = " ".join(map(repr, block.exits[0].args))
+ self.emit_edge(name, name2, label, style="solid")
+ elif numblocks >1:
+ i = 0
+ for link in block.exits:
+ name2 = self.blockname(link.target)
+ label = " ".join(map(repr, link.args))
+ label = "%s: %s" %(str(i), label)
+ self.emit_edge(name, name2, label, style="dotted")
+ i+=1
-def make_dot(fun, udir, target='ps'):
- dotgen = DotGen()
- name = fun.functionname
-
- from vpath.local import Path
+def make_dot(graph, storedir=None, target='ps'):
from vpath.adapter.process import exec_cmd
- dest = udir.join('%s.dot' % name)
- dest.write(dotgen.get_source(fun))
+
+ if storedir is None:
+ storedir = udir
+
+ dotgen = DotGen()
+ name = graph.name
+ dest = storedir.join('%s.dot' % name)
+ #dest = storedir.dirname().join('%s.dot' % name)
+ source = dotgen.get_source(graph)
+ #print source
+ dest.write(source)
psdest = dest.newext(target)
out = exec_cmd('dot -T%s %s' % (target, str(dest)))
psdest.write(out)
#print "wrote", psdest
return psdest
-if __name__ == '__main__':
- i = Variable("i")
- sum = Variable("sum")
-
- conditionres = Variable("conditionres")
- conditionop = SpaceOperation("gt", [i, Constant(0)], conditionres)
- decop = SpaceOperation("add", [i, Constant(-1)], i)
- addop = SpaceOperation("add", [i, sum], sum)
-
- conditionbranch = ConditionalBranch()
- headerbranch = Branch()
- headerbranch2 = Branch()
- whileblock = BasicBlock([i, sum], [i, sum], [addop, decop], headerbranch2)
- whilebranch = Branch([i, sum], whileblock)
-
- endbranch = EndBranch(sum)
- conditionbranch.set(conditionres, whilebranch, endbranch)
- headerblock = BasicBlock([i, sum], [i, conditionres],
- [conditionop], conditionbranch)
-
- headerbranch.set([i, Constant(0)], headerblock)
- headerbranch2.set([i, sum], headerblock)
- startblock = BasicBlock([i], [i, sum],
- [], headerbranch)
-
- startblock.prevblock = headerblock
-
- fun = FunctionGraph(startblock, "f")
-
- make_png(fun)
+if __name__ == '__main__':
+ def f(x):
+ i = 0
+ while i < x:
+ i += 1
+ return i
+
+ space = Space()
+ graph = space.build_flow(f)
+ make_dot(graph)
More information about the Pypy-commit
mailing list