diff options
| -rw-r--r-- | src/librustc_mir/build/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/transform/dump_mir.rs | 13 | ||||
| -rw-r--r-- | src/librustc_mir/transform/generator.rs | 8 | ||||
| -rw-r--r-- | src/librustc_mir/transform/nll/mod.rs | 24 | ||||
| -rw-r--r-- | src/librustc_mir/util/liveness.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/util/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/util/pretty.rs | 98 |
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, |
