Skip to content

Commit

Permalink
incr.comp.: Cache DepNodes with corresponding query results.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Jul 10, 2017
1 parent 0363a23 commit 6d049fb
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 35 deletions.
38 changes: 24 additions & 14 deletions src/librustc/dep_graph/edges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@ use super::debug::EdgeFilter;

pub struct DepGraphEdges {
nodes: Vec<DepNode>,
indices: FxHashMap<DepNode, IdIndex>,
edges: FxHashSet<(IdIndex, IdIndex)>,
indices: FxHashMap<DepNode, DepNodeIndex>,
edges: FxHashSet<(DepNodeIndex, DepNodeIndex)>,
task_stack: Vec<OpenTask>,
forbidden_edge: Option<EdgeFilter>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
struct IdIndex {
pub struct DepNodeIndex {
index: u32
}

impl IdIndex {
fn new(v: usize) -> IdIndex {
impl DepNodeIndex {

pub const INVALID: DepNodeIndex = DepNodeIndex { index: ::std::u32::MAX };

fn new(v: usize) -> DepNodeIndex {
assert!((v & 0xFFFF_FFFF) == v);
IdIndex { index: v as u32 }
DepNodeIndex { index: v as u32 }
}

fn index(self) -> usize {
Expand Down Expand Up @@ -80,7 +83,7 @@ impl DepGraphEdges {
}
}

fn id(&self, index: IdIndex) -> DepNode {
fn id(&self, index: DepNodeIndex) -> DepNode {
self.nodes[index.index()]
}

Expand All @@ -101,7 +104,7 @@ impl DepGraphEdges {
});
}

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

if let OpenTask::Regular {
Expand All @@ -117,6 +120,8 @@ impl DepGraphEdges {
let source_id = self.get_or_create_node(read);
self.edges.insert((source_id, target_id));
}

target_id
} else {
bug!("pop_task() - Expected regular task to be popped")
}
Expand All @@ -129,7 +134,7 @@ impl DepGraphEdges {
});
}

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

if let OpenTask::Anon {
Expand All @@ -155,8 +160,8 @@ impl DepGraphEdges {
hash: fingerprint,
};

if self.indices.contains_key(&target_dep_node) {
return target_dep_node;
if let Some(&index) = self.indices.get(&target_dep_node) {
return index;
}

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

target_dep_node
target_id
} else {
bug!("pop_anon_task() - Expected anonymous task to be popped")
}
Expand Down Expand Up @@ -210,6 +215,11 @@ impl DepGraphEdges {
}
}

pub fn read_index(&mut self, source: DepNodeIndex) {
let dep_node = self.nodes[source.index()];
self.read(dep_node);
}

pub fn query(&self) -> DepGraphQuery {
let edges: Vec<_> = self.edges.iter()
.map(|&(i, j)| (self.id(i), self.id(j)))
Expand All @@ -229,7 +239,7 @@ impl DepGraphEdges {
}

#[inline]
fn get_or_create_node(&mut self, dep_node: DepNode) -> IdIndex {
fn get_or_create_node(&mut self, dep_node: DepNode) -> DepNodeIndex {
let DepGraphEdges {
ref mut indices,
ref mut nodes,
Expand All @@ -239,7 +249,7 @@ impl DepGraphEdges {
*indices.entry(dep_node).or_insert_with(|| {
let next_id = nodes.len();
nodes.push(dep_node);
IdIndex::new(next_id)
DepNodeIndex::new(next_id)
})
}
}
32 changes: 25 additions & 7 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::dep_node::{DepNode, DepKind, WorkProductId};
use super::query::DepGraphQuery;
use super::raii;
use super::safe::DepGraphSafe;
use super::edges::DepGraphEdges;
use super::edges::{DepGraphEdges, DepNodeIndex};

#[derive(Clone)]
pub struct DepGraph {
Expand Down Expand Up @@ -108,16 +108,27 @@ impl DepGraph {
/// `arg` parameter.
///
/// [README]: README.md
pub fn with_task<C, A, R>(&self, key: DepNode, cx: C, arg: A, task: fn(C, A) -> R) -> R
where C: DepGraphSafe, A: DepGraphSafe
pub fn with_task<C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe
{
let _task = self.in_task(key);
task(cx, arg)
if let Some(ref data) = self.data {
data.edges.borrow_mut().push_task(key);
let result = task(cx, arg);
let dep_node_index = data.edges.borrow_mut().pop_task(key);
(result, dep_node_index)
} else {
(task(cx, arg), DepNodeIndex::INVALID)
}
}

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

Expand All @@ -137,6 +148,13 @@ impl DepGraph {
}
}

#[inline]
pub fn read_index(&self, v: DepNodeIndex) {
if let Some(ref data) = self.data {
data.edges.borrow_mut().read_index(v);
}
}

/// Only to be used during graph loading
#[inline]
pub fn add_edge_directly(&self, source: DepNode, target: DepNode) {
Expand Down
1 change: 1 addition & 0 deletions src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub use self::dep_node::DepNode;
pub use self::dep_node::WorkProductId;
pub use self::graph::DepGraph;
pub use self::graph::WorkProduct;
pub use self::edges::DepNodeIndex;
pub use self::query::DepGraphQuery;
pub use self::safe::AssertDepGraphSafe;
pub use self::safe::DepGraphSafe;
Expand Down
47 changes: 34 additions & 13 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

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

struct QueryMap<D: QueryDescription> {
phantom: PhantomData<D>,
map: FxHashMap<D::Key, D::Value>,
map: FxHashMap<D::Key, (D::Value, DepNodeIndex)>,
}

impl<M: QueryDescription> QueryMap<M> {
Expand Down Expand Up @@ -580,7 +580,8 @@ macro_rules! define_maps {
key,
span);

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

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

let _task = tcx.dep_graph.in_task(Self::to_dep_node(tcx, &key));

let result = tcx.cycle_check(span, Query::$name(key), || {
let provider = tcx.maps.providers[key.map_crate()].$name;
provider(tcx.global_tcx(), key)
let (result, dep_node_index) = tcx.cycle_check(span, Query::$name(key), || {
let dep_node = Self::to_dep_node(tcx, &key);

if dep_node.kind.is_anon() {
tcx.dep_graph.with_anon_task(dep_node.kind, || {
let provider = tcx.maps.providers[key.map_crate()].$name;
provider(tcx.global_tcx(), key)
})
} else {
fn run_provider<'a, 'tcx, 'lcx>(tcx: TyCtxt<'a, 'tcx, 'lcx>,
key: $K)
-> $V {
let provider = tcx.maps.providers[key.map_crate()].$name;
provider(tcx.global_tcx(), key)
}

tcx.dep_graph.with_task(dep_node, tcx, key, run_provider)
}
})?;

Ok(f(tcx.maps.$name.borrow_mut().map.entry(key).or_insert(result)))
tcx.dep_graph.read_index(dep_node_index);

Ok(f(&tcx.maps
.$name
.borrow_mut()
.map
.entry(key)
.or_insert((result, dep_node_index))
.0))
}

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

pub fn force(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K) {
// Ignore dependencies, since we not reading the computed value
let _task = tcx.dep_graph.in_ignore();

match Self::try_get_with(tcx, span, key, |_| ()) {
Ok(()) => {}
Err(e) => tcx.report_cycle(e)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.into_iter()
.map(|cgu| {
let dep_node = cgu.work_product_dep_node();
let (stats, module) =
let ((stats, module), _) =
tcx.dep_graph.with_task(dep_node,
AssertDepGraphSafe(&shared_ccx),
AssertDepGraphSafe(cgu),
Expand Down

0 comments on commit 6d049fb

Please sign in to comment.