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],