diff options
| author | bors <bors@rust-lang.org> | 2016-02-15 14:57:44 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-02-15 14:57:44 +0000 |
| commit | 7ce4afbddaa2e58378d8a61a4f6f96dc53acd956 (patch) | |
| tree | 1826a0c33403e19f9f1909019ece1d2c34a0c4fa | |
| parent | 3a254fe4bd10f630da76e89cbdc1275413a189d8 (diff) | |
| parent | 67aa7b2389a6dcea97d3d5f05fe3be8ece3acc6c (diff) | |
| download | rust-7ce4afbddaa2e58378d8a61a4f6f96dc53acd956.tar.gz rust-7ce4afbddaa2e58378d8a61a4f6f96dc53acd956.zip | |
Auto merge of #31656 - jonas-schievink:mirdump, r=nrc
This allows obtaining a textual MIR dump for individual items or all items in the crate.
I haven't added any tests since ~~I'm too lazy~~ this is an unstable debugging option, but I'll add one if required.
MIR for a single function can now be dumped using `rustc -Zunstable-options --unpretty mir=my_function` and no longer requires the use of in-source `#[rustc_mir]` attributes.
Blocks rust-lang/rust-playpen#154 (if MIR dump support from the playpen is even wanted).
Example output:
```rust
fn main() {
let x = Some(0);
x.unwrap_or_else(|| 1);
}
```
```
MIR for expr || 1 (id=16)
fn(arg0: [closure@test.rs:3:22: 3:26]) -> i32 {
let mut tmp0: ();
bb0: {
return = const 1;
goto -> bb1;
}
bb1: {
return;
}
}
MIR for fn main::main (id=4)
fn() -> () {
let var0: core::option::Option<i32>; // x
let mut tmp0: ();
let mut tmp1: i32;
let mut tmp2: core::option::Option<i32>;
let mut tmp3: [closure@test.rs:3:22: 3:26];
bb0: {
var0 = core::option::Option::Some(const 0);
tmp2 = var0;
tmp3 = [closure@test.rs:3:22: 3:26];
tmp1 = core::option::Option<T>::unwrap_or_else(tmp2, tmp3) -> bb2;
}
bb1: {
return;
}
bb2: {
drop(tmp1) -> bb3;
}
bb3: {
return = ();
goto -> bb1;
}
}
```
| -rw-r--r-- | src/librustc_driver/pretty.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4a82aa72825..05173578921 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -30,6 +30,8 @@ use rustc_borrowck::graphviz as borrowck_dot; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; +use rustc_mir::pretty::write_mir_pretty; + use syntax::ast::{self, BlockCheckMode}; use syntax::codemap; use syntax::fold::{self, Folder}; @@ -77,6 +79,7 @@ pub enum PpMode { PpmSource(PpSourceMode), PpmHir(PpSourceMode), PpmFlowGraph(PpFlowGraphMode), + PpmMir, } pub fn parse_pretty(sess: &Session, @@ -96,6 +99,7 @@ pub fn parse_pretty(sess: &Session, ("hir", true) => PpmHir(PpmNormal), ("hir,identified", true) => PpmHir(PpmIdentified), ("hir,typed", true) => PpmHir(PpmTyped), + ("mir", true) => PpmMir, ("flowgraph", true) => PpmFlowGraph(PpFlowGraphMode::Default), ("flowgraph,unlabelled", true) => PpmFlowGraph(PpFlowGraphMode::UnlabelledEdges), _ => { @@ -103,7 +107,7 @@ pub fn parse_pretty(sess: &Session, sess.fatal(&format!("argument to `unpretty` must be one of `normal`, \ `expanded`, `flowgraph[,unlabelled]=<nodeid>`, \ `identified`, `expanded,identified`, `everybody_loops`, \ - `hir`, `hir,identified`, or `hir,typed`; got {}", + `hir`, `hir,identified`, `hir,typed`, or `mir`; got {}", name)); } else { sess.fatal(&format!("argument to `pretty` must be one of `normal`, `expanded`, \ @@ -569,6 +573,7 @@ fn needs_ast_map(ppm: &PpMode, opt_uii: &Option<UserIdentifiedItem>) -> bool { PpmSource(PpmExpandedIdentified) | PpmSource(PpmExpandedHygiene) | PpmHir(_) | + PpmMir | PpmFlowGraph(_) => true, PpmSource(PpmTyped) => panic!("invalid state"), } @@ -584,6 +589,7 @@ fn needs_expansion(ppm: &PpMode) -> bool { PpmSource(PpmExpandedIdentified) | PpmSource(PpmExpandedHygiene) | PpmHir(_) | + PpmMir | PpmFlowGraph(_) => true, PpmSource(PpmTyped) => panic!("invalid state"), } @@ -801,6 +807,48 @@ pub fn pretty_print_input(sess: Session, }) } + (PpmMir, None) => { + debug!("pretty printing MIR for whole crate"); + let ast_map = ast_map.expect("--unpretty mir missing ast_map"); + abort_on_err(driver::phase_3_run_analysis_passes(&sess, + &cstore, + ast_map, + &arenas, + &id, + resolve::MakeGlobMap::No, + |tcx, mir_map, _, _| { + let mir_map = mir_map.unwrap(); + + for (nodeid, mir) in &mir_map.map { + try!(writeln!(out, "MIR for {}", tcx.map.node_to_string(*nodeid))); + try!(write_mir_pretty(mir, &mut out)); + } + + Ok(()) + }), &sess) + } + + (PpmMir, Some(uii)) => { + debug!("pretty printing MIR for {:?}", uii); + let ast_map = ast_map.expect("--unpretty mir missing ast_map"); + let nodeid = uii.to_one_node_id("--unpretty", &sess, &ast_map); + + abort_on_err(driver::phase_3_run_analysis_passes(&sess, + &cstore, + ast_map, + &arenas, + &id, + resolve::MakeGlobMap::No, + |tcx, mir_map, _, _| { + let mir_map = mir_map.unwrap(); + try!(writeln!(out, "MIR for {}", tcx.map.node_to_string(nodeid))); + let mir = mir_map.map.get(&nodeid).unwrap_or_else(|| { + sess.fatal(&format!("no MIR map entry for node {}", nodeid)) + }); + write_mir_pretty(mir, &mut out) + }), &sess) + } + (PpmFlowGraph(mode), opt_uii) => { debug!("pretty printing flow graph for {:?}", opt_uii); let uii = opt_uii.unwrap_or_else(|| { |
