Skip to content

Commit 8fdc72f

Browse files
committed
track MIR through the dep-graph
Per the discussion on #34765, we make one `DepNode::Mir` variant and use it to represent both the MIR tracking map as well as passes that operate on MIR. We also track loads of cached MIR (which naturally comes from metadata). Note that the "HAIR" pass adds a read of TypeckItemBody because it uses a myriad of tables that are not individually tracked.
1 parent 88b2e9a commit 8fdc72f

File tree

14 files changed

+127
-56
lines changed

14 files changed

+127
-56
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ pub enum DepNode<D: Clone + Debug> {
8282
Privacy,
8383
IntrinsicCheck(D),
8484
MatchCheck(D),
85-
MirMapConstruction(D),
86-
MirPass(D),
87-
MirTypeck(D),
85+
86+
// Represents the MIR for a fn; also used as the task node for
87+
// things read/modify that MIR.
88+
Mir(D),
89+
8890
BorrowCheck(D),
8991
RvalueCheck(D),
9092
Reachability,
@@ -214,9 +216,7 @@ impl<D: Clone + Debug> DepNode<D> {
214216
CheckConst(ref d) => op(d).map(CheckConst),
215217
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
216218
MatchCheck(ref d) => op(d).map(MatchCheck),
217-
MirMapConstruction(ref d) => op(d).map(MirMapConstruction),
218-
MirPass(ref d) => op(d).map(MirPass),
219-
MirTypeck(ref d) => op(d).map(MirTypeck),
219+
Mir(ref d) => op(d).map(Mir),
220220
BorrowCheck(ref d) => op(d).map(BorrowCheck),
221221
RvalueCheck(ref d) => op(d).map(RvalueCheck),
222222
TransCrateItem(ref d) => op(d).map(TransCrateItem),

src/librustc/dep_graph/dep_tracking_map.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ impl<M: DepTrackingMapConfig> DepTrackingMap<M> {
6161
self.map.get(k)
6262
}
6363

64+
pub fn get_mut(&mut self, k: &M::Key) -> Option<&mut M::Value> {
65+
self.read(k);
66+
self.write(k);
67+
self.map.get_mut(k)
68+
}
69+
6470
pub fn insert(&mut self, k: M::Key, v: M::Value) -> Option<M::Value> {
6571
self.write(&k);
6672
self.map.insert(k, v)
@@ -70,6 +76,10 @@ impl<M: DepTrackingMapConfig> DepTrackingMap<M> {
7076
self.read(k);
7177
self.map.contains_key(k)
7278
}
79+
80+
pub fn keys(&self) -> Vec<M::Key> {
81+
self.map.keys().cloned().collect()
82+
}
7383
}
7484

7585
impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {

src/librustc/mir/mir_map.rs

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

11-
use util::nodemap::NodeMap;
11+
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
12+
use hir::def_id::DefId;
1213
use mir::repr::Mir;
14+
use std::marker::PhantomData;
1315

1416
pub struct MirMap<'tcx> {
15-
pub map: NodeMap<Mir<'tcx>>,
17+
pub map: DepTrackingMap<MirMapConfig<'tcx>>,
18+
}
19+
20+
impl<'tcx> MirMap<'tcx> {
21+
pub fn new(graph: DepGraph) -> Self {
22+
MirMap {
23+
map: DepTrackingMap::new(graph)
24+
}
25+
}
26+
}
27+
28+
pub struct MirMapConfig<'tcx> {
29+
data: PhantomData<&'tcx ()>
30+
}
31+
32+
impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> {
33+
type Key = DefId;
34+
type Value = Mir<'tcx>;
35+
fn to_dep_node(key: &DefId) -> DepNode<DefId> {
36+
DepNode::Mir(*key)
37+
}
1638
}

src/librustc/mir/transform.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use dep_graph::DepNode;
1212
use hir;
1313
use hir::map::DefPathData;
14-
use hir::def_id::DefId;
1514
use mir::mir_map::MirMap;
1615
use mir::repr::{Mir, Promoted};
1716
use ty::TyCtxt;
@@ -73,9 +72,6 @@ impl<'a, 'tcx> MirSource {
7372
/// Various information about pass.
7473
pub trait Pass {
7574
// fn should_run(Session) to check if pass should run?
76-
fn dep_node(&self, def_id: DefId) -> DepNode<DefId> {
77-
DepNode::MirPass(def_id)
78-
}
7975
fn name(&self) -> &str {
8076
let name = unsafe { ::std::intrinsics::type_name::<Self>() };
8177
if let Some(tail) = name.rfind(":") {
@@ -119,10 +115,11 @@ impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
119115
map: &mut MirMap<'tcx>,
120116
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
121117
{
122-
for (&id, mir) in &mut map.map {
123-
let def_id = tcx.map.local_def_id(id);
124-
let _task = tcx.dep_graph.in_task(self.dep_node(def_id));
125-
118+
let def_ids = map.map.keys();
119+
for def_id in def_ids {
120+
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
121+
let mir = map.map.get_mut(&def_id).unwrap();
122+
let id = tcx.map.as_local_node_id(def_id).unwrap();
126123
let src = MirSource::from_node(tcx, id);
127124

128125
for hook in &mut *hooks {

src/librustc_borrowck/borrowck/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
168168
attributes: &[ast::Attribute]) {
169169
debug!("borrowck_fn(id={})", id);
170170

171+
let def_id = this.tcx.map.local_def_id(id);
172+
171173
if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
172-
let mir = this.mir_map.unwrap().map.get(&id).unwrap();
174+
let mir = this.mir_map.unwrap().map.get(&def_id).unwrap();
173175
this.with_temp_region_map(id, |this| {
174176
mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes)
175177
});

src/librustc_driver/pretty.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -956,20 +956,24 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
956956
PpmMir | PpmMirCFG => {
957957
if let Some(mir_map) = mir_map {
958958
if let Some(nodeid) = nodeid {
959-
let mir = mir_map.map.get(&nodeid).unwrap_or_else(|| {
960-
sess.fatal(&format!("no MIR map entry for node {}", nodeid))
961-
});
959+
let def_id = tcx.map.local_def_id(nodeid);
962960
match ppm {
963-
PpmMir => write_mir_pretty(tcx, iter::once((&nodeid, mir)), &mut out),
961+
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out),
964962
PpmMirCFG => {
965-
write_mir_graphviz(tcx, iter::once((&nodeid, mir)), &mut out)
963+
write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out)
966964
}
967965
_ => unreachable!(),
968966
}?;
969967
} else {
970968
match ppm {
971-
PpmMir => write_mir_pretty(tcx, mir_map.map.iter(), &mut out),
972-
PpmMirCFG => write_mir_graphviz(tcx, mir_map.map.iter(), &mut out),
969+
PpmMir => write_mir_pretty(tcx,
970+
mir_map.map.keys().into_iter(),
971+
&mir_map,
972+
&mut out),
973+
PpmMirCFG => write_mir_graphviz(tcx,
974+
mir_map.map.keys().into_iter(),
975+
&mir_map,
976+
&mut out),
973977
_ => unreachable!(),
974978
}?;
975979
}

src/librustc_metadata/encoder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,8 @@ fn encode_repr_attrs(rbml_w: &mut Encoder,
743743
}
744744

745745
fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, node_id: NodeId) {
746-
if let Some(mir) = ecx.mir_map.map.get(&node_id) {
746+
let def_id = ecx.tcx.map.local_def_id(node_id);
747+
if let Some(mir) = ecx.mir_map.map.get(&def_id) {
747748
rbml_w.start_tag(tag_mir as usize);
748749
rbml_w.emit_opaque(|opaque_encoder| {
749750
tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| {
@@ -1361,7 +1362,7 @@ fn my_visit_expr(expr: &hir::Expr,
13611362
ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap();
13621363
rbml_w.end_tag();
13631364

1364-
assert!(ecx.mir_map.map.contains_key(&expr.id));
1365+
assert!(ecx.mir_map.map.contains_key(&def_id));
13651366
encode_mir(ecx, rbml_w, expr.id);
13661367

13671368
rbml_w.end_tag();

src/librustc_mir/graphviz.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
// except according to those terms.
1010

1111
use dot;
12+
use rustc::hir::def_id::DefId;
1213
use rustc::mir::repr::*;
14+
use rustc::mir::mir_map::MirMap;
1315
use rustc::ty::{self, TyCtxt};
1416
use std::fmt::Debug;
1517
use std::io::{self, Write};
@@ -19,10 +21,16 @@ use rustc_data_structures::indexed_vec::Idx;
1921

2022
/// Write a graphviz DOT graph of a list of MIRs.
2123
pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
22-
iter: I, w: &mut W)
24+
iter: I,
25+
mir_map: &MirMap<'tcx>,
26+
w: &mut W)
2327
-> io::Result<()>
24-
where W: Write, I: Iterator<Item=(&'a NodeId, &'a Mir<'a>)> {
25-
for (&nodeid, mir) in iter {
28+
where W: Write, I: Iterator<Item=DefId>
29+
{
30+
for def_id in iter {
31+
let nodeid = tcx.map.as_local_node_id(def_id).unwrap();
32+
let mir = &mir_map.map[&def_id];
33+
2634
writeln!(w, "digraph Mir_{} {{", nodeid)?;
2735

2836
// Global graph properties

src/librustc_mir/hair/cx/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::mir::transform::MirSource;
2222
use rustc::middle::const_val::ConstVal;
2323
use rustc_const_eval as const_eval;
2424
use rustc_data_structures::indexed_vec::Idx;
25+
use rustc::dep_graph::DepNode;
2526
use rustc::hir::def_id::DefId;
2627
use rustc::hir::intravisit::FnKind;
2728
use rustc::hir::map::blocks::FnLikeNode;
@@ -61,7 +62,17 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
6162
MirSource::Promoted(..) => bug!()
6263
};
6364

64-
let attrs = infcx.tcx.map.attrs(src.item_id());
65+
let src_node_id = src.item_id();
66+
67+
// We are going to be accessing various tables
68+
// generated by TypeckItemBody; we also assume
69+
// that the body passes type check. These tables
70+
// are not individually tracked, so just register
71+
// a read here.
72+
let src_def_id = infcx.tcx.map.local_def_id(src_node_id);
73+
infcx.tcx.dep_graph.read(DepNode::TypeckItemBody(src_def_id));
74+
75+
let attrs = infcx.tcx.map.attrs(src_node_id);
6576

6677
// Some functions always have overflow checks enabled,
6778
// however, they may not get codegen'd, depending on

src/librustc_mir/mir_map.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
use build;
2020
use rustc::dep_graph::DepNode;
21+
use rustc::hir::def_id::DefId;
2122
use rustc::mir::repr::Mir;
2223
use rustc::mir::transform::MirSource;
2324
use rustc::mir::visit::MutVisitor;
@@ -29,7 +30,6 @@ use rustc::infer::InferCtxtBuilder;
2930
use rustc::traits::ProjectionMode;
3031
use rustc::ty::{self, Ty, TyCtxt};
3132
use rustc::ty::subst::Substs;
32-
use rustc::util::nodemap::NodeMap;
3333
use rustc::hir;
3434
use rustc::hir::intravisit::{self, FnKind, Visitor};
3535
use syntax::ast;
@@ -38,15 +38,13 @@ use syntax_pos::Span;
3838
use std::mem;
3939

4040
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> {
41-
let mut map = MirMap {
42-
map: NodeMap(),
43-
};
41+
let mut map = MirMap::new(tcx.dep_graph.clone());
4442
{
4543
let mut dump = BuildMir {
4644
tcx: tcx,
4745
map: &mut map,
4846
};
49-
tcx.visit_all_items_in_krate(DepNode::MirMapConstruction, &mut dump);
47+
tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump);
5048
}
5149
map
5250
}
@@ -94,16 +92,19 @@ struct BuildMir<'a, 'tcx: 'a> {
9492
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Cx<'b, 'gcx, 'tcx>).
9593
struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
9694
src: MirSource,
95+
def_id: DefId,
9796
infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>,
9897
map: &'a mut MirMap<'gcx>,
9998
}
10099

101100
impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
102101
fn cx<'b>(&'b mut self, src: MirSource) -> CxBuilder<'b, 'gcx, 'tcx> {
103102
let param_env = ty::ParameterEnvironment::for_item(self.tcx, src.item_id());
103+
let def_id = self.tcx.map.local_def_id(src.item_id());
104104
CxBuilder {
105105
src: src,
106106
infcx: self.tcx.infer_ctxt(None, Some(param_env), ProjectionMode::AnyFinal),
107+
def_id: def_id,
107108
map: self.map
108109
}
109110
}
@@ -133,7 +134,7 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
133134
mir
134135
});
135136

136-
assert!(self.map.map.insert(src.item_id(), mir).is_none())
137+
assert!(self.map.map.insert(self.def_id, mir).is_none())
137138
}
138139
}
139140

0 commit comments

Comments
 (0)