about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/build/mod.rs4
-rw-r--r--src/librustc_mir/transform/dump_mir.rs13
-rw-r--r--src/librustc_mir/transform/generator.rs8
-rw-r--r--src/librustc_mir/transform/nll/mod.rs24
-rw-r--r--src/librustc_mir/util/liveness.rs2
-rw-r--r--src/librustc_mir/util/mod.rs2
-rw-r--r--src/librustc_mir/util/pretty.rs98
7 files changed, 107 insertions, 44 deletions
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 46a5e5abbdd..b8bb2a40462 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -149,7 +149,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
             mem::transmute::<Mir, Mir<'tcx>>(mir)
         };
 
-        mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
+        mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir, |_, _| Ok(()) );
 
         mir
     })
@@ -227,7 +227,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 mem::transmute::<Mir, Mir<'tcx>>(mir)
             };
 
-            mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
+            mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir, |_, _| Ok(()) );
 
             mir
         })
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 67a3281dba4..cea66837d9a 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -65,7 +65,18 @@ impl PassHook for DumpMir {
                                pass_name,
                                &Disambiguator { is_after },
                                source,
-                               mir);
+                               mir,
+                               |_, _| Ok(()) );
+            for (index, promoted_mir) in mir.promoted.iter_enumerated() {
+                let promoted_source = MirSource::Promoted(source.item_id(), index);
+                mir_util::dump_mir(tcx,
+                                   Some((suite, pass_num)),
+                                   pass_name,
+                                   &Disambiguator { is_after },
+                                   promoted_source,
+                                   promoted_mir,
+                                   |_, _| Ok(()) );
+            }
         }
     }
 }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 729fe46ef37..7d0814b67fb 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -587,7 +587,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
     // unrelated code from the resume part of the function
     simplify::remove_dead_blocks(&mut mir);
 
-    dump_mir(tcx, None, "generator_drop", &0, source, &mut mir);
+    dump_mir(tcx, None, "generator_drop", &0, source, &mut mir, |_, _| Ok(()) );
 
     mir
 }
@@ -673,7 +673,7 @@ fn create_generator_resume_function<'a, 'tcx>(
     // unrelated code from the drop part of the function
     simplify::remove_dead_blocks(mir);
 
-    dump_mir(tcx, None, "generator_resume", &0, source, mir);
+    dump_mir(tcx, None, "generator_resume", &0, source, mir, |_, _| Ok(()) );
 }
 
 fn source_info<'a, 'tcx>(mir: &Mir<'tcx>) -> SourceInfo {
@@ -816,14 +816,14 @@ impl MirPass for StateTransform {
         // This is expanded to a drop ladder in `elaborate_generator_drops`.
         let drop_clean = insert_clean_drop(mir);
 
-        dump_mir(tcx, None, "generator_pre-elab", &0, source, mir);
+        dump_mir(tcx, None, "generator_pre-elab", &0, source, mir, |_, _| Ok(()) );
 
         // Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
         // If any upvars are moved out of, drop elaboration will handle upvar destruction.
         // However we need to also elaborate the code generated by `insert_clean_drop`.
         elaborate_generator_drops(tcx, def_id, mir);
 
-        dump_mir(tcx, None, "generator_post-transform", &0, source, mir);
+        dump_mir(tcx, None, "generator_post-transform", &0, source, mir, |_, _| Ok(()) );
 
         // Create a copy of our MIR and use it to create the drop shim for the generator
         let drop_shim = create_generator_drop_shim(tcx,
diff --git a/src/librustc_mir/transform/nll/mod.rs b/src/librustc_mir/transform/nll/mod.rs
index d4a5354c78f..4925b1fcfed 100644
--- a/src/librustc_mir/transform/nll/mod.rs
+++ b/src/librustc_mir/transform/nll/mod.rs
@@ -19,6 +19,10 @@ use rustc::util::nodemap::FxHashSet;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use syntax_pos::DUMMY_SP;
 use std::collections::HashMap;
+use std::fmt;
+
+use util as mir_util;
+use self::mir_util::PassWhere;
 
 #[allow(dead_code)]
 struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -134,7 +138,7 @@ pub struct NLL;
 impl MirPass for NLL {
     fn run_pass<'a, 'tcx>(&self,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          _: MirSource,
+                          source: MirSource,
                           mir: &mut Mir<'tcx>) {
         if !tcx.sess.opts.debugging_opts.nll {
             return;
@@ -145,14 +149,30 @@ impl MirPass for NLL {
             let mut renumbered_mir = mir.clone();
             let mut visitor = NLLVisitor::new(infcx);
             visitor.visit_mir(&mut renumbered_mir);
+            mir_util::dump_mir(tcx, None, "nll", &0, source, mir, |pass_where, out| {
+                if let PassWhere::BeforeCFG = pass_where {
+                    for (index, value) in visitor.regions.iter_enumerated() {
+                        writeln!(out, "// R{:03}: {:?}", index.0, value)?;
+                    }
+                }
+                Ok(())
+            });
             let _results = visitor.into_results();
         })
     }
 }
 
-#[derive(Clone, Debug, Default, PartialEq, Eq)]
+#[derive(Clone, Default, PartialEq, Eq)]
 struct Region {
     points: FxHashSet<Location>,
 }
 
+impl fmt::Debug for Region {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(formatter, "{:?}", self.points)
+    }
+}
+
+
+
 newtype_index!(RegionIndex);
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index e6d3a82ff9b..1424c063d73 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -232,7 +232,7 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             writeln!(w, "{} {{{}}}", prefix, live.join(", "))
         };
         print(w, "   ", &result.ins)?;
-        write_basic_block(tcx, block, mir, w)?;
+        write_basic_block(tcx, block, mir, &mut |_, _| Ok(()), w)?;
         print(w, "   ", &result.outs)?;
         if block.index() + 1 != mir.basic_blocks().len() {
             writeln!(w, "")?;
diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs
index 4b6da96824d..13c14f8920f 100644
--- a/src/librustc_mir/util/mod.rs
+++ b/src/librustc_mir/util/mod.rs
@@ -17,6 +17,6 @@ mod graphviz;
 mod pretty;
 pub mod liveness;
 
-pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty};
+pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
 pub use self::graphviz::{write_mir_graphviz};
 pub use self::graphviz::write_node_label as write_graphviz_node_label;
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 9e1f05f6d2f..8a9047fb491 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -25,6 +25,22 @@ const INDENT: &'static str = "    ";
 /// Alignment for lining up comments following MIR statements
 const ALIGN: usize = 40;
 
+/// An indication of where we are in the control flow graph. Used for printing
+/// extra information in `dump_mir`
+pub enum PassWhere {
+    /// We have not started dumping the control flow graph, but we are about to.
+    BeforeCFG,
+
+    /// We just finished dumping the control flow graph. This is right before EOF
+    AfterCFG,
+
+    /// We are about to start dumping the given basic block.
+    BeforeBlock(BasicBlock),
+
+    /// We are just about to dumpt the given statement or terminator.
+    InCFG(Location),
+}
+
 /// If the session is properly configured, dumps a human-readable
 /// representation of the mir into:
 ///
@@ -39,12 +55,16 @@ const ALIGN: usize = 40;
 /// - `substring1&substring2,...` -- `&`-separated list of substrings
 ///   that can appear in the pass-name or the `item_path_str` for the given
 ///   node-id. If any one of the substrings match, the data is dumped out.
-pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          pass_num: Option<(MirSuite, MirPassIndex)>,
-                          pass_name: &str,
-                          disambiguator: &Display,
-                          source: MirSource,
-                          mir: &Mir<'tcx>) {
+pub fn dump_mir<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                             pass_num: Option<(MirSuite, MirPassIndex)>,
+                             pass_name: &str,
+                             disambiguator: &Display,
+                             source: MirSource,
+                             mir: &Mir<'tcx>,
+                             extra_data: F)
+where
+    F: FnMut(PassWhere, &mut Write) -> io::Result<()>
+{
     if !dump_enabled(tcx, pass_name, source) {
         return;
     }
@@ -53,12 +73,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         tcx.item_path_str(tcx.hir.local_def_id(source.item_id()))
     });
     dump_matched_mir_node(tcx, pass_num, pass_name, &node_path,
-                          disambiguator, source, mir);
-    for (index, promoted_mir) in mir.promoted.iter_enumerated() {
-        let promoted_source = MirSource::Promoted(source.item_id(), index);
-        dump_matched_mir_node(tcx, pass_num, pass_name, &node_path, disambiguator,
-                              promoted_source, promoted_mir);
-    }
+                          disambiguator, source, mir, extra_data);
 }
 
 pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -85,13 +100,17 @@ pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 // `item_path_str()` would otherwise trigger `type_of`, and this can
 // run while we are already attempting to evaluate `type_of`.
 
-fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                   pass_num: Option<(MirSuite, MirPassIndex)>,
-                                   pass_name: &str,
-                                   node_path: &str,
-                                   disambiguator: &Display,
-                                   source: MirSource,
-                                   mir: &Mir<'tcx>) {
+fn dump_matched_mir_node<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                      pass_num: Option<(MirSuite, MirPassIndex)>,
+                                      pass_name: &str,
+                                      node_path: &str,
+                                      disambiguator: &Display,
+                                      source: MirSource,
+                                      mir: &Mir<'tcx>,
+                                      mut extra_data: F)
+where
+    F: FnMut(PassWhere, &mut Write) -> io::Result<()>
+{
     let promotion_id = match source {
         MirSource::Promoted(_, id) => format!("-{:?}", id),
         MirSource::GeneratorDrop(_) => format!("-drop"),
@@ -125,7 +144,9 @@ fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             writeln!(file, "// generator_layout = {:?}", layout)?;
         }
         writeln!(file, "")?;
-        write_mir_fn(tcx, source, mir, &mut file)?;
+        extra_data(PassWhere::BeforeCFG, &mut file)?;
+        write_mir_fn(tcx, source, mir, &mut extra_data, &mut file)?;
+        extra_data(PassWhere::AfterCFG, &mut file)?;
         Ok(())
     });
 }
@@ -152,24 +173,29 @@ pub fn write_mir_pretty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         let id = tcx.hir.as_local_node_id(def_id).unwrap();
         let src = MirSource::from_node(tcx, id);
-        write_mir_fn(tcx, src, mir, w)?;
+        write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?;
 
         for (i, mir) in mir.promoted.iter_enumerated() {
             writeln!(w, "")?;
-            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w)?;
+            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, &mut |_, _| Ok(()), w)?;
         }
     }
     Ok(())
 }
 
-pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              src: MirSource,
-                              mir: &Mir<'tcx>,
-                              w: &mut Write)
-                              -> io::Result<()> {
+pub fn write_mir_fn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                 src: MirSource,
+                                 mir: &Mir<'tcx>,
+                                 extra_data: &mut F,
+                                 w: &mut Write)
+                                 -> io::Result<()>
+where
+    F: FnMut(PassWhere, &mut Write) -> io::Result<()>
+{
     write_mir_intro(tcx, src, mir, w)?;
     for block in mir.basic_blocks().indices() {
-        write_basic_block(tcx, block, mir, w)?;
+        extra_data(PassWhere::BeforeBlock(block), w)?;
+        write_basic_block(tcx, block, mir, extra_data, w)?;
         if block.index() + 1 != mir.basic_blocks().len() {
             writeln!(w, "")?;
         }
@@ -180,11 +206,15 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 /// Write out a human-readable textual representation for the given basic block.
-pub fn write_basic_block(tcx: TyCtxt,
-                     block: BasicBlock,
-                     mir: &Mir,
-                     w: &mut Write)
-                     -> io::Result<()> {
+pub fn write_basic_block<F>(tcx: TyCtxt,
+                            block: BasicBlock,
+                            mir: &Mir,
+                            extra_data: &mut F,
+                            w: &mut Write)
+                            -> io::Result<()>
+where
+    F: FnMut(PassWhere, &mut Write) -> io::Result<()>
+{
     let data = &mir[block];
 
     // Basic block label at the top.
@@ -195,6 +225,7 @@ pub fn write_basic_block(tcx: TyCtxt,
     // List of statements in the middle.
     let mut current_location = Location { block: block, statement_index: 0 };
     for statement in &data.statements {
+        extra_data(PassWhere::InCFG(current_location), w)?;
         let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
         writeln!(w, "{0:1$} // {2}",
                  indented_mir,
@@ -205,6 +236,7 @@ pub fn write_basic_block(tcx: TyCtxt,
     }
 
     // Terminator at the bottom.
+    extra_data(PassWhere::InCFG(current_location), w)?;
     let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
     writeln!(w, "{0:1$} // {2}",
              indented_terminator,