structure F = Frame fun getInstrList filename = let val frags as mainfrag::_ = Main.getfrags filename fun getInstrs (Frame.PROC{body,frame}) = let val stms = Canon.linearize body val stms' = Canon.traceSchedule(Canon.basicBlocks stms) val instrs = List.concat(map (IA32Gen.codegen frame) stms') in instrs end | getInstrs (Frame.STRING(_,_)) = nil val instrs = getInstrs mainfrag in instrs end fun putDotInfo(gnodes, instrs, out) = let fun output(str) = TextIO.output(out,str) fun printConnection(nodeName, nil) = () | printConnection(nodeName, x::xs) = (output ("\t" ^ nodeName ^ " -> " ^ Graph.nodename(x) ^ "\n"); printConnection(nodeName, xs)) fun showConnection(node) = printConnection(Graph.nodename(node), Graph.succ(node)) val format0 = Assem.format(Main.makestring) fun unEscape(str) = let fun f(#"\t" :: rest) = (#" " :: f rest) | f(#"\n" :: rest) = f rest | f(c :: rest) = (c :: f rest) | f nil = nil val result = implode(f(explode str)) in if result = "" then "(nop)" else result end val idx = ref 0 fun printNodeInfo(instr) = let val baseStr = format0 instr val unEscStr = unEscape(baseStr) in (output("\tn" ^ Int.toString(!idx) ^ " [shape=box,label=\"" ^ unEscStr ^ "\"]\n"); idx := !idx + 1) end in (output("digraph G {\n"); output("\tsize = \"4,15\";\n"); output("\tranksep = .4\n"); app showConnection gnodes; app (fn i => printNodeInfo i) instrs; output("}\n")) end fun writeGraphFile(filename) = let val instrs = getInstrList filename val (graph,nodes) = MakeGraph.instrs2graph instrs fun getControl(Flow.FGRAPH{control,...}) = control val gnodes = Graph.nodes(getControl(graph)) in Main.withOpenFile (filename ^ ".dot") (fn out => putDotInfo(gnodes,instrs,out)) end