Skip to content

Commit 6d049fb

Browse files
incr.comp.: Cache DepNodes with corresponding query results.
1 parent 0363a23 commit 6d049fb

File tree

5 files changed

+85
-35
lines changed

5 files changed

+85
-35
lines changed

src/librustc/dep_graph/edges.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ use super::debug::EdgeFilter;
1919

2020
pub struct DepGraphEdges {
2121
nodes: Vec<DepNode>,
22-
indices: FxHashMap<DepNode, IdIndex>,
23-
edges: FxHashSet<(IdIndex, IdIndex)>,
22+
indices: FxHashMap<DepNode, DepNodeIndex>,
23+
edges: FxHashSet<(DepNodeIndex, DepNodeIndex)>,
2424
task_stack: Vec<OpenTask>,
2525
forbidden_edge: Option<EdgeFilter>,
2626
}
2727

2828
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
29-
struct IdIndex {
29+
pub struct DepNodeIndex {
3030
index: u32
3131
}
3232

33-
impl IdIndex {
34-
fn new(v: usize) -> IdIndex {
33+
impl DepNodeIndex {
34+
35+
pub const INVALID: DepNodeIndex = DepNodeIndex { index: ::std::u32::MAX };
36+
37+
fn new(v: usize) -> DepNodeIndex {
3538
assert!((v & 0xFFFF_FFFF) == v);
36-
IdIndex { index: v as u32 }
39+
DepNodeIndex { index: v as u32 }
3740
}
3841

3942
fn index(self) -> usize {
@@ -80,7 +83,7 @@ impl DepGraphEdges {
8083
}
8184
}
8285

83-
fn id(&self, index: IdIndex) -> DepNode {
86+
fn id(&self, index: DepNodeIndex) -> DepNode {
8487
self.nodes[index.index()]
8588
}
8689

@@ -101,7 +104,7 @@ impl DepGraphEdges {
101104
});
102105
}
103106

104-
pub fn pop_task(&mut self, key: DepNode) {
107+
pub fn pop_task(&mut self, key: DepNode) -> DepNodeIndex {
105108
let popped_node = self.task_stack.pop().unwrap();
106109

107110
if let OpenTask::Regular {
@@ -117,6 +120,8 @@ impl DepGraphEdges {
117120
let source_id = self.get_or_create_node(read);
118121
self.edges.insert((source_id, target_id));
119122
}
123+
124+
target_id
120125
} else {
121126
bug!("pop_task() - Expected regular task to be popped")
122127
}
@@ -129,7 +134,7 @@ impl DepGraphEdges {
129134
});
130135
}
131136

132-
pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNode {
137+
pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndex {
133138
let popped_node = self.task_stack.pop().unwrap();
134139

135140
if let OpenTask::Anon {
@@ -155,8 +160,8 @@ impl DepGraphEdges {
155160
hash: fingerprint,
156161
};
157162

158-
if self.indices.contains_key(&target_dep_node) {
159-
return target_dep_node;
163+
if let Some(&index) = self.indices.get(&target_dep_node) {
164+
return index;
160165
}
161166

162167
let target_id = self.get_or_create_node(target_dep_node);
@@ -166,7 +171,7 @@ impl DepGraphEdges {
166171
self.edges.insert((source_id, target_id));
167172
}
168173

169-
target_dep_node
174+
target_id
170175
} else {
171176
bug!("pop_anon_task() - Expected anonymous task to be popped")
172177
}
@@ -210,6 +215,11 @@ impl DepGraphEdges {
210215
}
211216
}
212217

218+
pub fn read_index(&mut self, source: DepNodeIndex) {
219+
let dep_node = self.nodes[source.index()];
220+
self.read(dep_node);
221+
}
222+
213223
pub fn query(&self) -> DepGraphQuery {
214224
let edges: Vec<_> = self.edges.iter()
215225
.map(|&(i, j)| (self.id(i), self.id(j)))
@@ -229,7 +239,7 @@ impl DepGraphEdges {
229239
}
230240

231241
#[inline]
232-
fn get_or_create_node(&mut self, dep_node: DepNode) -> IdIndex {
242+
fn get_or_create_node(&mut self, dep_node: DepNode) -> DepNodeIndex {
233243
let DepGraphEdges {
234244
ref mut indices,
235245
ref mut nodes,
@@ -239,7 +249,7 @@ impl DepGraphEdges {
239249
*indices.entry(dep_node).or_insert_with(|| {
240250
let next_id = nodes.len();
241251
nodes.push(dep_node);
242-
IdIndex::new(next_id)
252+
DepNodeIndex::new(next_id)
243253
})
244254
}
245255
}

src/librustc/dep_graph/graph.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use super::dep_node::{DepNode, DepKind, WorkProductId};
1717
use super::query::DepGraphQuery;
1818
use super::raii;
1919
use super::safe::DepGraphSafe;
20-
use super::edges::DepGraphEdges;
20+
use super::edges::{DepGraphEdges, DepNodeIndex};
2121

2222
#[derive(Clone)]
2323
pub struct DepGraph {
@@ -108,16 +108,27 @@ impl DepGraph {
108108
/// `arg` parameter.
109109
///
110110
/// [README]: README.md
111-
pub fn with_task<C, A, R>(&self, key: DepNode, cx: C, arg: A, task: fn(C, A) -> R) -> R
112-
where C: DepGraphSafe, A: DepGraphSafe
111+
pub fn with_task<C, A, R>(&self,
112+
key: DepNode,
113+
cx: C,
114+
arg: A,
115+
task: fn(C, A) -> R)
116+
-> (R, DepNodeIndex)
117+
where C: DepGraphSafe
113118
{
114-
let _task = self.in_task(key);
115-
task(cx, arg)
119+
if let Some(ref data) = self.data {
120+
data.edges.borrow_mut().push_task(key);
121+
let result = task(cx, arg);
122+
let dep_node_index = data.edges.borrow_mut().pop_task(key);
123+
(result, dep_node_index)
124+
} else {
125+
(task(cx, arg), DepNodeIndex::INVALID)
126+
}
116127
}
117128

118129
/// Execute something within an "anonymous" task, that is, a task the
119130
/// DepNode of which is determined by the list of inputs it read from.
120-
pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNode)
131+
pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex)
121132
where OP: FnOnce() -> R
122133
{
123134
if let Some(ref data) = self.data {
@@ -126,7 +137,7 @@ impl DepGraph {
126137
let dep_node = data.edges.borrow_mut().pop_anon_task(dep_kind);
127138
(result, dep_node)
128139
} else {
129-
(op(), DepNode::new_no_params(DepKind::Krate))
140+
(op(), DepNodeIndex::INVALID)
130141
}
131142
}
132143

@@ -137,6 +148,13 @@ impl DepGraph {
137148
}
138149
}
139150

151+
#[inline]
152+
pub fn read_index(&self, v: DepNodeIndex) {
153+
if let Some(ref data) = self.data {
154+
data.edges.borrow_mut().read_index(v);
155+
}
156+
}
157+
140158
/// Only to be used during graph loading
141159
#[inline]
142160
pub fn add_edge_directly(&self, source: DepNode, target: DepNode) {

src/librustc/dep_graph/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub use self::dep_node::DepNode;
2222
pub use self::dep_node::WorkProductId;
2323
pub use self::graph::DepGraph;
2424
pub use self::graph::WorkProduct;
25+
pub use self::edges::DepNodeIndex;
2526
pub use self::query::DepGraphQuery;
2627
pub use self::safe::AssertDepGraphSafe;
2728
pub use self::safe::DepGraphSafe;

src/librustc/ty/maps.rs

+34-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use dep_graph::{DepConstructor, DepNode};
11+
use dep_graph::{DepConstructor, DepNode, DepNodeIndex};
1212
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
1313
use hir::def::Def;
1414
use hir;
@@ -186,7 +186,7 @@ impl<'tcx> Value<'tcx> for ty::SymbolName {
186186

187187
struct QueryMap<D: QueryDescription> {
188188
phantom: PhantomData<D>,
189-
map: FxHashMap<D::Key, D::Value>,
189+
map: FxHashMap<D::Key, (D::Value, DepNodeIndex)>,
190190
}
191191

192192
impl<M: QueryDescription> QueryMap<M> {
@@ -580,7 +580,8 @@ macro_rules! define_maps {
580580
key,
581581
span);
582582

583-
if let Some(result) = tcx.maps.$name.borrow().map.get(&key) {
583+
if let Some(&(ref result, dep_node_index)) = tcx.maps.$name.borrow().map.get(&key) {
584+
tcx.dep_graph.read_index(dep_node_index);
584585
return Ok(f(result));
585586
}
586587

@@ -591,26 +592,46 @@ macro_rules! define_maps {
591592
span = key.default_span(tcx)
592593
}
593594

594-
let _task = tcx.dep_graph.in_task(Self::to_dep_node(tcx, &key));
595-
596-
let result = tcx.cycle_check(span, Query::$name(key), || {
597-
let provider = tcx.maps.providers[key.map_crate()].$name;
598-
provider(tcx.global_tcx(), key)
595+
let (result, dep_node_index) = tcx.cycle_check(span, Query::$name(key), || {
596+
let dep_node = Self::to_dep_node(tcx, &key);
597+
598+
if dep_node.kind.is_anon() {
599+
tcx.dep_graph.with_anon_task(dep_node.kind, || {
600+
let provider = tcx.maps.providers[key.map_crate()].$name;
601+
provider(tcx.global_tcx(), key)
602+
})
603+
} else {
604+
fn run_provider<'a, 'tcx, 'lcx>(tcx: TyCtxt<'a, 'tcx, 'lcx>,
605+
key: $K)
606+
-> $V {
607+
let provider = tcx.maps.providers[key.map_crate()].$name;
608+
provider(tcx.global_tcx(), key)
609+
}
610+
611+
tcx.dep_graph.with_task(dep_node, tcx, key, run_provider)
612+
}
599613
})?;
600614

601-
Ok(f(tcx.maps.$name.borrow_mut().map.entry(key).or_insert(result)))
615+
tcx.dep_graph.read_index(dep_node_index);
616+
617+
Ok(f(&tcx.maps
618+
.$name
619+
.borrow_mut()
620+
.map
621+
.entry(key)
622+
.or_insert((result, dep_node_index))
623+
.0))
602624
}
603625

604626
pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
605627
-> Result<$V, CycleError<'a, $tcx>> {
606-
// We register the `read` here, but not in `force`, since
607-
// `force` does not give access to the value produced (and thus
608-
// we actually don't read it).
609-
tcx.dep_graph.read(Self::to_dep_node(tcx, &key));
610628
Self::try_get_with(tcx, span, key, Clone::clone)
611629
}
612630

613631
pub fn force(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K) {
632+
// Ignore dependencies, since we not reading the computed value
633+
let _task = tcx.dep_graph.in_ignore();
634+
614635
match Self::try_get_with(tcx, span, key, |_| ()) {
615636
Ok(()) => {}
616637
Err(e) => tcx.report_cycle(e)

src/librustc_trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11201120
.into_iter()
11211121
.map(|cgu| {
11221122
let dep_node = cgu.work_product_dep_node();
1123-
let (stats, module) =
1123+
let ((stats, module), _) =
11241124
tcx.dep_graph.with_task(dep_node,
11251125
AssertDepGraphSafe(&shared_ccx),
11261126
AssertDepGraphSafe(cgu),

0 commit comments

Comments
 (0)