Skip to content

Commit 916c0b8

Browse files
authored
Rollup merge of rust-lang#39891 - shepmaster:emit-mir, r=nikomatsakis
Teach rustc --emit=mir I'm opening this PR to discuss: 1. Is this a good idea? 1. Is this a good implementation? I'm sure people will have opinions on both points! This spawned from rust-lang#31847 (comment), so I figured a prototype implementation could help provide a seed to talk about.
2 parents c62e532 + 4ddedf7 commit 916c0b8

File tree

5 files changed

+32
-0
lines changed

5 files changed

+32
-0
lines changed

src/librustc/session/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pub enum OutputType {
8282
Bitcode,
8383
Assembly,
8484
LlvmAssembly,
85+
Mir,
8586
Metadata,
8687
Object,
8788
Exe,
@@ -96,6 +97,7 @@ impl OutputType {
9697
OutputType::Bitcode |
9798
OutputType::Assembly |
9899
OutputType::LlvmAssembly |
100+
OutputType::Mir |
99101
OutputType::Object |
100102
OutputType::Metadata => false,
101103
}
@@ -106,6 +108,7 @@ impl OutputType {
106108
OutputType::Bitcode => "llvm-bc",
107109
OutputType::Assembly => "asm",
108110
OutputType::LlvmAssembly => "llvm-ir",
111+
OutputType::Mir => "mir",
109112
OutputType::Object => "obj",
110113
OutputType::Metadata => "metadata",
111114
OutputType::Exe => "link",
@@ -118,6 +121,7 @@ impl OutputType {
118121
OutputType::Bitcode => "bc",
119122
OutputType::Assembly => "s",
120123
OutputType::LlvmAssembly => "ll",
124+
OutputType::Mir => "mir",
121125
OutputType::Object => "o",
122126
OutputType::Metadata => "rmeta",
123127
OutputType::DepInfo => "d",
@@ -172,6 +176,7 @@ impl OutputTypes {
172176
OutputType::Bitcode |
173177
OutputType::Assembly |
174178
OutputType::LlvmAssembly |
179+
OutputType::Mir |
175180
OutputType::Object |
176181
OutputType::Exe => true,
177182
OutputType::Metadata |
@@ -1370,6 +1375,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
13701375
let output_type = match parts.next().unwrap() {
13711376
"asm" => OutputType::Assembly,
13721377
"llvm-ir" => OutputType::LlvmAssembly,
1378+
"mir" => OutputType::Mir,
13731379
"llvm-bc" => OutputType::Bitcode,
13741380
"obj" => OutputType::Object,
13751381
"metadata" => OutputType::Metadata,

src/librustc_driver/driver.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ pub fn compile_input(sess: &Session,
209209
tcx.print_debug_stats();
210210
}
211211

212+
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
213+
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) {
214+
sess.err(&format!("could not emit MIR: {}", e));
215+
sess.abort_if_errors();
216+
}
217+
}
218+
212219
Ok((outputs, trans))
213220
})??
214221
};

src/librustc_mir/transform/dump_mir.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
//! This pass just dumps MIR at a specified point.
1212
1313
use std::fmt;
14+
use std::fs::File;
15+
use std::io;
1416

17+
use rustc::session::config::{OutputFilenames, OutputType};
1518
use rustc::ty::TyCtxt;
1619
use rustc::mir::*;
1720
use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource};
@@ -70,3 +73,14 @@ impl<'tcx> MirPassHook<'tcx> for DumpMir {
7073
}
7174

7275
impl<'b> Pass for DumpMir {}
76+
77+
pub fn emit_mir<'a, 'tcx>(
78+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
79+
outputs: &OutputFilenames)
80+
-> io::Result<()>
81+
{
82+
let path = outputs.path(OutputType::Mir);
83+
let mut f = File::create(&path)?;
84+
mir_util::write_mir_pretty(tcx, tcx.maps.mir.borrow().keys().into_iter(), &mut f)?;
85+
Ok(())
86+
}

src/librustc_mir/util/pretty.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
9191
-> io::Result<()>
9292
where I: Iterator<Item=DefId>, 'tcx: 'a
9393
{
94+
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
95+
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
96+
9497
let mut first = true;
9598
for def_id in iter.filter(DefId::is_local) {
9699
let mir = &tcx.item_mir(def_id);

src/librustc_trans/back/write.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ pub fn run_passes(sess: &Session,
741741
modules_config.emit_obj = true;
742742
metadata_config.emit_obj = true;
743743
},
744+
OutputType::Mir => {}
744745
OutputType::DepInfo => {}
745746
}
746747
}
@@ -880,6 +881,7 @@ pub fn run_passes(sess: &Session,
880881
user_wants_objects = true;
881882
copy_if_one_unit(OutputType::Object, true);
882883
}
884+
OutputType::Mir |
883885
OutputType::Metadata |
884886
OutputType::Exe |
885887
OutputType::DepInfo => {}

0 commit comments

Comments
 (0)