From 08b1fe39c2f263ed9df49c445f65ce0b118d1a07 Mon Sep 17 00:00:00 2001 From: Mikhail Modin <mikhailm1@gmail.com> Date: Tue, 24 Oct 2017 14:48:39 +0300 Subject: [PATCH 1/2] add graphvis DOT files to dump mir directory --- src/librustc/session/config.rs | 4 +++ src/librustc_mir/util/graphviz.rs | 43 +++++++++++++++++++------------ src/librustc_mir/util/pretty.rs | 9 +++++++ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index fc1c5e187ecc7..db439c0787cbe 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1057,6 +1057,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "dump MIR state at various points in translation"), dump_mir_dir: Option<String> = (None, parse_opt_string, [UNTRACKED], "the directory the MIR is dumped into"), + dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], + "additionally to `.mir` files, create graphviz `.dot` files"), dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], "if set, exclude the pass number when dumping MIR (used in tests)"), mir_emit_validate: usize = (0, parse_uint, [TRACKED], @@ -2650,6 +2652,8 @@ mod tests { assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts.debugging_opts.dump_mir_dir = Some(String::from("abc")); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + opts.debugging_opts.dump_mir_graphviz = true; + assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); // Make sure changing a [TRACKED] option changes the hash opts = reference.clone(); diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index cf13a80e677b1..cec8067530b61 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -30,29 +30,38 @@ pub fn write_mir_graphviz<'a, 'tcx, W>(tcx: TyCtxt<'a, 'tcx, 'tcx>, for def_id in dump_mir_def_ids(tcx, single) { let nodeid = tcx.hir.as_local_node_id(def_id).unwrap(); let mir = &tcx.optimized_mir(def_id); + write_mir_fn_graphviz(tcx, nodeid, mir, w)?; + } + Ok(()) +} - writeln!(w, "digraph Mir_{} {{", nodeid)?; +/// Write a graphviz DOT graph of the MIR. +pub fn write_mir_fn_graphviz<'a, 'tcx, W>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + nodeid: NodeId, + mir: &Mir, + w: &mut W) -> io::Result<()> + where W: Write +{ + writeln!(w, "digraph Mir_{} {{", nodeid)?; - // Global graph properties - writeln!(w, r#" graph [fontname="monospace"];"#)?; - writeln!(w, r#" node [fontname="monospace"];"#)?; - writeln!(w, r#" edge [fontname="monospace"];"#)?; + // Global graph properties + writeln!(w, r#" graph [fontname="monospace"];"#)?; + writeln!(w, r#" node [fontname="monospace"];"#)?; + writeln!(w, r#" edge [fontname="monospace"];"#)?; - // Graph label - write_graph_label(tcx, nodeid, mir, w)?; + // Graph label + write_graph_label(tcx, nodeid, mir, w)?; - // Nodes - for (block, _) in mir.basic_blocks().iter_enumerated() { - write_node(block, mir, w)?; - } + // Nodes + for (block, _) in mir.basic_blocks().iter_enumerated() { + write_node(block, mir, w)?; + } - // Edges - for (source, _) in mir.basic_blocks().iter_enumerated() { - write_edges(source, mir, w)?; - } - writeln!(w, "}}")? + // Edges + for (source, _) in mir.basic_blocks().iter_enumerated() { + write_edges(source, mir, w)?; } - Ok(()) + writeln!(w, "}}") } /// Write a graphviz HTML-styled label for the given basic block, with diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 9e1f05f6d2f77..61914a6fc36d4 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -20,6 +20,7 @@ use std::fmt::Display; use std::fs; use std::io::{self, Write}; use std::path::{PathBuf, Path}; +use super::graphviz::write_mir_fn_graphviz; const INDENT: &'static str = " "; /// Alignment for lining up comments following MIR statements @@ -128,6 +129,14 @@ fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, write_mir_fn(tcx, source, mir, &mut file)?; Ok(()) }); + + if tcx.sess.opts.debugging_opts.dump_mir_graphviz { + file_path.set_extension("dot"); + let _ = fs::File::create(&file_path).and_then(|mut file| { + write_mir_fn_graphviz(tcx, source.item_id(), mir, &mut file)?; + Ok(()) + }); + } } /// Write out a human-readable textual representation for the given MIR. From b2c2ba4eb53329672f0965d2d643049fc4417835 Mon Sep 17 00:00:00 2001 From: Niko Matsakis <niko@alum.mit.edu> Date: Mon, 30 Oct 2017 10:22:35 -0400 Subject: [PATCH 2/2] tweak the description "in addition to" sounds better than "additionally to" --- src/librustc/session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index db439c0787cbe..4838083cf8254 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1058,7 +1058,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, dump_mir_dir: Option<String> = (None, parse_opt_string, [UNTRACKED], "the directory the MIR is dumped into"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], - "additionally to `.mir` files, create graphviz `.dot` files"), + "in addition to `.mir` files, create graphviz `.dot` files"), dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], "if set, exclude the pass number when dumping MIR (used in tests)"), mir_emit_validate: usize = (0, parse_uint, [TRACKED],