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

src/librustc_mir/pretty.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
use build::{Location, ScopeAuxiliaryVec, ScopeId};
1212
use rustc::hir;
13+
use rustc::hir::def_id::DefId;
1314
use rustc::mir::repr::*;
15+
use rustc::mir::mir_map::MirMap;
1416
use rustc::mir::transform::MirSource;
1517
use rustc::ty::{self, TyCtxt};
1618
use rustc_data_structures::fnv::FnvHashMap;
1719
use rustc_data_structures::indexed_vec::{Idx};
1820
use std::fmt::Display;
1921
use std::fs;
2022
use std::io::{self, Write};
21-
use syntax::ast::NodeId;
2223
use std::path::{PathBuf, Path};
2324

2425
const INDENT: &'static str = " ";
@@ -89,19 +90,23 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
8990
/// Write out a human-readable textual representation for the given MIR.
9091
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
9192
iter: I,
93+
mir_map: &MirMap<'tcx>,
9294
w: &mut Write)
9395
-> io::Result<()>
94-
where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
96+
where I: Iterator<Item=DefId>, 'tcx: 'a
9597
{
9698
let mut first = true;
97-
for (&id, mir) in iter {
99+
for def_id in iter {
100+
let mir = &mir_map.map[&def_id];
101+
98102
if first {
99103
first = false;
100104
} else {
101105
// Put empty lines between all items
102106
writeln!(w, "")?;
103107
}
104108

109+
let id = tcx.map.as_local_node_id(def_id).unwrap();
105110
let src = MirSource::from_node(tcx, id);
106111
write_mir_fn(tcx, src, mir, w, None)?;
107112

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use rustc_data_structures::bitvec::BitVector;
1818
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
19+
use rustc::dep_graph::DepNode;
1920
use rustc::hir;
2021
use rustc::hir::def_id::DefId;
2122
use rustc::hir::intravisit::FnKind;
@@ -881,8 +882,8 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
881882

882883
let extern_mir;
883884
let param_env_and_mir = if def_id.is_local() {
884-
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
885-
mir_map.and_then(|map| map.map.get(&node_id)).map(|mir| {
885+
mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| {
886+
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
886887
(ty::ParameterEnvironment::for_item(tcx, node_id), mir)
887888
})
888889
} else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) {
@@ -917,9 +918,10 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
917918

918919
// First, visit `const` items, potentially recursing, to get
919920
// accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications.
920-
for &id in map.map.keys() {
921-
let def_id = tcx.map.local_def_id(id);
922-
let _task = tcx.dep_graph.in_task(self.dep_node(def_id));
921+
let keys = map.map.keys();
922+
for &def_id in &keys {
923+
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
924+
let id = tcx.map.as_local_node_id(def_id).unwrap();
923925
let src = MirSource::from_node(tcx, id);
924926
if let MirSource::Const(_) = src {
925927
qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id);
@@ -929,9 +931,9 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
929931
// Then, handle everything else, without recursing,
930932
// as the MIR map is not shared, since promotion
931933
// in functions (including `const fn`) mutates it.
932-
for (&id, mir) in &mut map.map {
933-
let def_id = tcx.map.local_def_id(id);
934-
let _task = tcx.dep_graph.in_task(self.dep_node(def_id));
934+
for &def_id in &keys {
935+
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
936+
let id = tcx.map.as_local_node_id(def_id).unwrap();
935937
let src = MirSource::from_node(tcx, id);
936938
let mode = match src {
937939
MirSource::Fn(_) => {
@@ -948,6 +950,7 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
948950
};
949951
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
950952

953+
let mir = map.map.get_mut(&def_id).unwrap();
951954
for hook in &mut *hooks {
952955
hook.on_mir_pass(tcx, src, mir, self, false);
953956
}

0 commit comments

Comments
 (0)