Skip to content

incr.comp.: Deduplicate some DepNodes and introduce anonymous DepNodes #43028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 11, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this is fine for now, but it'd be nicer to use Nonzero so that we can (efficiently) use Option<DepNodeIndex>, I suspect.


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