diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d7a765fb822..a0603c57952 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -82,6 +82,7 @@ pub enum OutputType { Bitcode, Assembly, LlvmAssembly, + Mir, Metadata, Object, Exe, @@ -96,6 +97,7 @@ impl OutputType { OutputType::Bitcode | OutputType::Assembly | OutputType::LlvmAssembly | + OutputType::Mir | OutputType::Object | OutputType::Metadata => false, } @@ -106,6 +108,7 @@ impl OutputType { OutputType::Bitcode => "llvm-bc", OutputType::Assembly => "asm", OutputType::LlvmAssembly => "llvm-ir", + OutputType::Mir => "mir", OutputType::Object => "obj", OutputType::Metadata => "metadata", OutputType::Exe => "link", @@ -118,6 +121,7 @@ impl OutputType { OutputType::Bitcode => "bc", OutputType::Assembly => "s", OutputType::LlvmAssembly => "ll", + OutputType::Mir => "mir", OutputType::Object => "o", OutputType::Metadata => "rmeta", OutputType::DepInfo => "d", @@ -172,6 +176,7 @@ impl OutputTypes { OutputType::Bitcode | OutputType::Assembly | OutputType::LlvmAssembly | + OutputType::Mir | OutputType::Object | OutputType::Exe => true, OutputType::Metadata | @@ -1370,6 +1375,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let output_type = match parts.next().unwrap() { "asm" => OutputType::Assembly, "llvm-ir" => OutputType::LlvmAssembly, + "mir" => OutputType::Mir, "llvm-bc" => OutputType::Bitcode, "obj" => OutputType::Object, "metadata" => OutputType::Metadata, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 2126a5a7c71..c1ea2b9ce41 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -209,6 +209,13 @@ pub fn compile_input(sess: &Session, tcx.print_debug_stats(); } + if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { + if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) { + sess.err(&format!("could not emit MIR: {}", e)); + sess.abort_if_errors(); + } + } + Ok((outputs, trans)) })?? }; diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index f22a71636a9..5b3113f962b 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -11,7 +11,10 @@ //! This pass just dumps MIR at a specified point. use std::fmt; +use std::fs::File; +use std::io; +use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource}; @@ -70,3 +73,14 @@ impl<'tcx> MirPassHook<'tcx> for DumpMir { } impl<'b> Pass for DumpMir {} + +pub fn emit_mir<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + outputs: &OutputFilenames) + -> io::Result<()> +{ + let path = outputs.path(OutputType::Mir); + let mut f = File::create(&path)?; + mir_util::write_mir_pretty(tcx, tcx.maps.mir.borrow().keys().into_iter(), &mut f)?; + Ok(()) +} diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 35734dcce2b..ef2bf6e5434 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -91,6 +91,9 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, -> io::Result<()> where I: Iterator, 'tcx: 'a { + writeln!(w, "// WARNING: This output format is intended for human consumers only")?; + writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; + let mut first = true; for def_id in iter.filter(DefId::is_local) { let mir = &tcx.item_mir(def_id); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 40a69721495..377ff34cb7e 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -741,6 +741,7 @@ pub fn run_passes(sess: &Session, modules_config.emit_obj = true; metadata_config.emit_obj = true; }, + OutputType::Mir => {} OutputType::DepInfo => {} } } @@ -880,6 +881,7 @@ pub fn run_passes(sess: &Session, user_wants_objects = true; copy_if_one_unit(OutputType::Object, true); } + OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {}