Skip to content

Commit 363ac0f

Browse files
committed
Factor out MIR printer into a pass
1 parent af69f95 commit 363ac0f

File tree

5 files changed

+81
-55
lines changed

5 files changed

+81
-55
lines changed

src/librustc/dep_graph/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub enum DepNode {
7070
IntrinsicCheck(DefId),
7171
MatchCheck(DefId),
7272
MirMapConstruction(DefId),
73+
MirPrintPass,
7374
BorrowCheck(DefId),
7475
RvalueCheck(DefId),
7576
Reachability,

src/librustc_driver/driver.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
856856
// Push all the built-in passes.
857857
passes.push_pass(box transform::simplify_cfg::SimplifyCfg);
858858
passes.push_pass(box transform::erase_regions::EraseRegions);
859+
passes.push_pass(box transform::print::MirPrint);
859860
passes.push_pass(box transform::simplify_cfg::CompactMir);
860861
// And run everything.
861862
passes.run_passes(tcx, &mut mir_map);

src/librustc_mir/mir_map.rs

Lines changed: 5 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! An experimental pass that scources for `#[rustc_mir]` attributes,
12-
//! builds the resulting MIR, and dumps it out into a file for inspection.
13-
//!
14-
//! The attribute formats that are currently accepted are:
15-
//!
16-
//! - `#[rustc_mir(graphviz="file.gv")]`
17-
//! - `#[rustc_mir(pretty="file.mir")]`
11+
//! An pass that builds the MIR for each item and stores it into the map.
1812
1913
extern crate syntax;
2014
extern crate rustc_front;
2115

2216
use build;
23-
use graphviz;
24-
use pretty;
2517
use rustc::dep_graph::DepNode;
2618
use rustc::mir::repr::Mir;
2719
use hair::cx::Cx;
28-
use std::fs::File;
2920

3021
use rustc::mir::mir_map::MirMap;
3122
use rustc::middle::infer;
@@ -133,55 +124,14 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
133124
body: &'tcx hir::Block,
134125
span: Span,
135126
id: ast::NodeId) {
136-
let (prefix, implicit_arg_tys) = match fk {
137-
intravisit::FnKind::Closure =>
138-
(format!("{}-", id), vec![closure_self_ty(&self.tcx, id, body.id)]),
139-
_ =>
140-
(format!(""), vec![]),
127+
let implicit_arg_tys = match fk {
128+
intravisit::FnKind::Closure => vec![closure_self_ty(&self.tcx, id, body.id)],
129+
_ => vec![],
141130
};
142-
143131
let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
144-
145132
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env));
146-
147133
match build_mir(Cx::new(&infcx), implicit_arg_tys, id, span, decl, body) {
148-
Ok(mir) => {
149-
let meta_item_list = self.attr
150-
.iter()
151-
.flat_map(|a| a.meta_item_list())
152-
.flat_map(|l| l.iter());
153-
for item in meta_item_list {
154-
if item.check_name("graphviz") || item.check_name("pretty") {
155-
match item.value_str() {
156-
Some(s) => {
157-
let filename = format!("{}{}", prefix, s);
158-
let result = File::create(&filename).and_then(|ref mut output| {
159-
if item.check_name("graphviz") {
160-
graphviz::write_mir_graphviz(&mir, output)
161-
} else {
162-
pretty::write_mir_pretty(&mir, output)
163-
}
164-
});
165-
166-
if let Err(e) = result {
167-
self.tcx.sess.span_fatal(
168-
item.span,
169-
&format!("Error writing MIR {} results to `{}`: {}",
170-
item.name(), filename, e));
171-
}
172-
}
173-
None => {
174-
self.tcx.sess.span_err(
175-
item.span,
176-
&format!("{} attribute requires a path", item.name()));
177-
}
178-
}
179-
}
180-
}
181-
182-
let previous = self.map.map.insert(id, mir);
183-
assert!(previous.is_none());
184-
}
134+
Ok(mir) => assert!(self.map.map.insert(id, mir).is_none()),
185135
Err(ErrorReported) => {}
186136
}
187137

src/librustc_mir/transform/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010

1111
pub mod simplify_cfg;
1212
pub mod erase_regions;
13+
pub mod print;
1314
mod util;

src/librustc_mir/transform/print.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! This pass handles the `#[rustc_mir(*)]` attributes and prints the contents.
12+
//!
13+
//! The attribute formats that are currently accepted are:
14+
//!
15+
//! - `#[rustc_mir(graphviz="file.gv")]`
16+
//! - `#[rustc_mir(pretty="file.mir")]`
17+
use graphviz;
18+
use pretty;
19+
20+
use syntax::attr::AttrMetaMethods;
21+
use rustc::middle::ty;
22+
use rustc::dep_graph::DepNode;
23+
use rustc::mir::mir_map::MirMap;
24+
use rustc::mir::transform::{MirMapPass, Pass};
25+
26+
use std::fs::File;
27+
28+
pub struct MirPrint;
29+
30+
impl Pass for MirPrint {
31+
fn priority(&self) -> usize {
32+
// This is a late pass, because we usually want to see the Mir post-passes.
33+
!100
34+
}
35+
}
36+
37+
impl MirMapPass for MirPrint {
38+
fn run_pass<'tcx>(&mut self, tcx: &ty::ctxt<'tcx>, map: &mut MirMap<'tcx>) {
39+
let _task = tcx.map.dep_graph.in_task(DepNode::MirPrintPass);
40+
for (node_id, mir) in &map.map {
41+
for attr in tcx.map.attrs(*node_id) {
42+
if !attr.check_name("rustc_mir") {
43+
continue
44+
}
45+
for arg in attr.meta_item_list().iter().flat_map(|e| *e) {
46+
if arg.check_name("graphviz") || arg.check_name("pretty") {
47+
let filename = if let Some(p) = arg.value_str() {
48+
p
49+
} else {
50+
tcx.sess.span_err(arg.span,
51+
&format!("{} attribute requires a path", arg.name())
52+
);
53+
continue
54+
};
55+
let result = File::create(&*filename).and_then(|ref mut output| {
56+
if arg.check_name("graphviz") {
57+
graphviz::write_mir_graphviz(&mir, output)
58+
} else {
59+
pretty::write_mir_pretty(&mir, output)
60+
}
61+
});
62+
63+
if let Err(e) = result {
64+
tcx.sess.span_err(arg.span,
65+
&format!("Error writing MIR {} output to `{}`: {}",
66+
arg.name(), filename, e));
67+
}
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)