diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/util/graphviz.rs | 52 | ||||
| -rw-r--r-- | src/librustc_mir/util/pretty.rs | 2 | ||||
| -rw-r--r-- | src/test/mir-opt/graphviz.rs | 11 |
3 files changed, 45 insertions, 20 deletions
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 7fcb7a40a3c..ff2946d3a69 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -16,10 +16,22 @@ pub fn write_mir_graphviz<W>( where W: Write, { - for def_id in dump_mir_def_ids(tcx, single) { + let def_ids = dump_mir_def_ids(tcx, single); + + let use_subgraphs = def_ids.len() > 1; + if use_subgraphs { + writeln!(w, "digraph __crate__ {{")?; + } + + for def_id in def_ids { let body = &tcx.optimized_mir(def_id); - write_mir_fn_graphviz(tcx, def_id, body, w)?; + write_mir_fn_graphviz(tcx, def_id, body, use_subgraphs, w)?; } + + if use_subgraphs { + writeln!(w, "}}")?; + } + Ok(()) } @@ -38,12 +50,16 @@ pub fn write_mir_fn_graphviz<'tcx, W>( tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'_>, + subgraph: bool, w: &mut W, ) -> io::Result<()> where W: Write, { - writeln!(w, "digraph Mir_{} {{", graphviz_safe_def_name(def_id))?; + let kind = if subgraph { "subgraph" } else { "digraph" }; + let cluster = if subgraph { "cluster_" } else { "" }; // Prints a border around MIR + let def_name = graphviz_safe_def_name(def_id); + writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?; // Global graph properties writeln!(w, r#" graph [fontname="monospace"];"#)?; @@ -55,12 +71,12 @@ where // Nodes for (block, _) in body.basic_blocks().iter_enumerated() { - write_node(block, body, w)?; + write_node(def_id, block, body, w)?; } // Edges for (source, _) in body.basic_blocks().iter_enumerated() { - write_edges(source, body, w)?; + write_edges(def_id, source, body, w)?; } writeln!(w, "}}") } @@ -111,25 +127,37 @@ pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock, fini(w)?; // Close the table - writeln!(w, "</table>") + write!(w, "</table>") } /// Write a graphviz DOT node for the given basic block. -fn write_node<W: Write>(block: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> { +fn write_node<W: Write>( + def_id: DefId, + block: BasicBlock, + body: &Body<'_>, + w: &mut W, +) -> io::Result<()> { // Start a new node with the label to follow, in one of DOT's pseudo-HTML tables. - write!(w, r#" {} [shape="none", label=<"#, node(block))?; + write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?; write_node_label(block, body, w, 1, |_| Ok(()), |_| Ok(()))?; // Close the node label and the node itself. writeln!(w, ">];") } /// Write graphviz DOT edges with labels between the given basic block and all of its successors. -fn write_edges<W: Write>(source: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> { +fn write_edges<W: Write>( + def_id: DefId, + source: BasicBlock, + body: &Body<'_>, + w: &mut W, +) -> io::Result<()> { let terminator = body[source].terminator(); let labels = terminator.kind.fmt_successor_labels(); for (&target, label) in terminator.successors().zip(labels) { - writeln!(w, r#" {} -> {} [label="{}"];"#, node(source), node(target), label)?; + let src = node(def_id, source); + let trg = node(def_id, target); + writeln!(w, r#" {} -> {} [label="{}"];"#, src, trg, label)?; } Ok(()) @@ -181,8 +209,8 @@ fn write_graph_label<'tcx, W: Write>( writeln!(w, ">;") } -fn node(block: BasicBlock) -> String { - format!("bb{}", block.index()) +fn node(def_id: DefId, block: BasicBlock) -> String { + format!("bb{}__{}", block.index(), graphviz_safe_def_name(def_id)) } fn escape<T: Debug>(t: &T) -> String { diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 7f6b60b1b11..89f298846d2 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -145,7 +145,7 @@ fn dump_matched_mir_node<'tcx, F>( let _: io::Result<()> = try { let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?; - write_mir_fn_graphviz(tcx, source.def_id(), body, &mut file)?; + write_mir_fn_graphviz(tcx, source.def_id(), body, false, &mut file)?; }; } } diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs index 67a6d1d263b..fdd4e226c5a 100644 --- a/src/test/mir-opt/graphviz.rs +++ b/src/test/mir-opt/graphviz.rs @@ -12,12 +12,9 @@ fn main() {} // node [fontname="monospace"]; // edge [fontname="monospace"]; // label=<fn main() -> ()<br align="left"/>>; -// bb0 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table> -// >]; -// bb1 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table> -// >]; -// bb2 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table> -// >]; -// bb0 -> bb2 [label=""]; +// bb0__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>]; +// bb1__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>]; +// bb2__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>>]; +// bb0__0_12 -> bb2__0_12 [label=""]; // } // END rustc.main.mir_map.0.dot |
