[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