Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
84 changes: 42 additions & 42 deletions compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::bug;
use rustc_middle::dep_graph::{DepGraphQuery, DepKind, DepNode, DepNodeFilter, EdgeFilter};
use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeFilter, EdgeFilter, RetainedDepGraph};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_span::{Span, Symbol, sym};
Expand All @@ -57,7 +57,7 @@ use crate::errors;
pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) {
tcx.dep_graph.with_ignore(|| {
if tcx.sess.opts.unstable_opts.dump_dep_graph {
tcx.dep_graph.with_query(dump_graph);
tcx.dep_graph.with_retained_dep_graph(dump_graph);
}

if !tcx.sess.opts.unstable_opts.query_dep_graph {
Expand Down Expand Up @@ -184,7 +184,7 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
}
return;
}
tcx.dep_graph.with_query(|query| {
tcx.dep_graph.with_retained_dep_graph(|query| {
for &(_, source_def_id, ref source_dep_node) in if_this_changed {
let dependents = query.transitive_predecessors(source_dep_node);
for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need {
Expand All @@ -202,21 +202,21 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
});
}

fn dump_graph(query: &DepGraphQuery) {
fn dump_graph(graph: &RetainedDepGraph) {
let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| "dep_graph".to_string());

let nodes = match env::var("RUST_DEP_GRAPH_FILTER") {
Ok(string) => {
// Expect one of: "-> target", "source -> target", or "source ->".
let edge_filter =
EdgeFilter::new(&string).unwrap_or_else(|e| bug!("invalid filter: {}", e));
let sources = node_set(query, &edge_filter.source);
let targets = node_set(query, &edge_filter.target);
filter_nodes(query, &sources, &targets)
let sources = node_set(graph, &edge_filter.source);
let targets = node_set(graph, &edge_filter.target);
filter_nodes(graph, &sources, &targets)
}
Err(_) => query.nodes().into_iter().map(|n| n.kind).collect(),
Err(_) => graph.nodes().into_iter().map(|n| n.kind).collect(),
};
let edges = filter_edges(query, &nodes);
let edges = filter_edges(graph, &nodes);

{
// dump a .txt file with just the edges:
Expand Down Expand Up @@ -279,51 +279,51 @@ impl<'a> dot::Labeller<'a> for GraphvizDepGraph {
// Given an optional filter like `"x,y,z"`, returns either `None` (no
// filter) or the set of nodes whose labels contain all of those
// substrings.
fn node_set<'q>(
query: &'q DepGraphQuery,
fn node_set<'g>(
graph: &'g RetainedDepGraph,
filter: &DepNodeFilter,
) -> Option<FxIndexSet<&'q DepNode>> {
) -> Option<FxIndexSet<&'g DepNode>> {
debug!("node_set(filter={:?})", filter);

if filter.accepts_all() {
return None;
}

Some(query.nodes().into_iter().filter(|n| filter.test(n)).collect())
Some(graph.nodes().into_iter().filter(|n| filter.test(n)).collect())
}

fn filter_nodes<'q>(
query: &'q DepGraphQuery,
sources: &Option<FxIndexSet<&'q DepNode>>,
targets: &Option<FxIndexSet<&'q DepNode>>,
fn filter_nodes<'g>(
graph: &'g RetainedDepGraph,
sources: &Option<FxIndexSet<&'g DepNode>>,
targets: &Option<FxIndexSet<&'g DepNode>>,
) -> FxIndexSet<DepKind> {
if let Some(sources) = sources {
if let Some(targets) = targets {
walk_between(query, sources, targets)
walk_between(graph, sources, targets)
} else {
walk_nodes(query, sources, OUTGOING)
walk_nodes(graph, sources, OUTGOING)
}
} else if let Some(targets) = targets {
walk_nodes(query, targets, INCOMING)
walk_nodes(graph, targets, INCOMING)
} else {
query.nodes().into_iter().map(|n| n.kind).collect()
graph.nodes().into_iter().map(|n| n.kind).collect()
}
}

fn walk_nodes<'q>(
query: &'q DepGraphQuery,
starts: &FxIndexSet<&'q DepNode>,
fn walk_nodes<'g>(
graph: &'g RetainedDepGraph,
starts: &FxIndexSet<&'g DepNode>,
direction: Direction,
) -> FxIndexSet<DepKind> {
let mut set = FxIndexSet::default();
for &start in starts {
debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING);
if set.insert(start.kind) {
let mut stack = vec![query.indices[start]];
let mut stack = vec![graph.indices[start]];
while let Some(index) = stack.pop() {
for (_, edge) in query.graph.adjacent_edges(index, direction) {
for (_, edge) in graph.inner.adjacent_edges(index, direction) {
let neighbor_index = edge.source_or_target(direction);
let neighbor = query.graph.node_data(neighbor_index);
let neighbor = graph.inner.node_data(neighbor_index);
if set.insert(neighbor.kind) {
stack.push(neighbor_index);
}
Expand All @@ -334,10 +334,10 @@ fn walk_nodes<'q>(
set
}

fn walk_between<'q>(
query: &'q DepGraphQuery,
sources: &FxIndexSet<&'q DepNode>,
targets: &FxIndexSet<&'q DepNode>,
fn walk_between<'g>(
graph: &'g RetainedDepGraph,
sources: &FxIndexSet<&'g DepNode>,
targets: &FxIndexSet<&'g DepNode>,
) -> FxIndexSet<DepKind> {
// This is a bit tricky. We want to include a node only if it is:
// (a) reachable from a source and (b) will reach a target. And we
Expand All @@ -352,27 +352,27 @@ fn walk_between<'q>(
Excluded,
}

let mut node_states = vec![State::Undecided; query.graph.len_nodes()];
let mut node_states = vec![State::Undecided; graph.inner.len_nodes()];

for &target in targets {
node_states[query.indices[target].0] = State::Included;
node_states[graph.indices[target].0] = State::Included;
}

for source in sources.iter().map(|&n| query.indices[n]) {
recurse(query, &mut node_states, source);
for source in sources.iter().map(|&n| graph.indices[n]) {
recurse(graph, &mut node_states, source);
}

return query
return graph
.nodes()
.into_iter()
.filter(|&n| {
let index = query.indices[n];
let index = graph.indices[n];
node_states[index.0] == State::Included
})
.map(|n| n.kind)
.collect();

fn recurse(query: &DepGraphQuery, node_states: &mut [State], node: NodeIndex) -> bool {
fn recurse(graph: &RetainedDepGraph, node_states: &mut [State], node: NodeIndex) -> bool {
match node_states[node.0] {
// known to reach a target
State::Included => return true,
Expand All @@ -388,8 +388,8 @@ fn walk_between<'q>(

node_states[node.0] = State::Deciding;

for neighbor_index in query.graph.successor_nodes(node) {
if recurse(query, node_states, neighbor_index) {
for neighbor_index in graph.inner.successor_nodes(node) {
if recurse(graph, node_states, neighbor_index) {
node_states[node.0] = State::Included;
}
}
Expand All @@ -405,8 +405,8 @@ fn walk_between<'q>(
}
}

fn filter_edges(query: &DepGraphQuery, nodes: &FxIndexSet<DepKind>) -> Vec<(DepKind, DepKind)> {
let uniq: FxIndexSet<_> = query
fn filter_edges(graph: &RetainedDepGraph, nodes: &FxIndexSet<DepKind>) -> Vec<(DepKind, DepKind)> {
let uniq: FxIndexSet<_> = graph
.edges()
.into_iter()
.map(|(s, t)| (s.kind, t.kind))
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use tracing::{debug, instrument};
#[cfg(debug_assertions)]
use {super::debug::EdgeFilter, std::env};

use super::query::DepGraphQuery;
use super::retained::RetainedDepGraph;
use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
use super::{DepKind, DepNode, WorkProductId, read_deps, with_deps};
use crate::dep_graph::edges::EdgesVec;
Expand Down Expand Up @@ -191,9 +191,9 @@ impl DepGraph {
self.data.is_some()
}

pub fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
pub fn with_retained_dep_graph(&self, f: impl Fn(&RetainedDepGraph)) {
if let Some(data) = &self.data {
data.current.encoder.with_query(f)
data.current.encoder.with_retained_dep_graph(f)
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use self::graph::{
WorkProductMap, hash_result,
};
use self::graph::{MarkFrame, print_markframe_trace};
pub use self::query::DepGraphQuery;
pub use self::retained::RetainedDepGraph;
pub use self::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
pub use crate::dep_graph::debug::{DepNodeFilter, EdgeFilter};
use crate::ty::print::with_reduced_queries;
Expand All @@ -21,7 +21,7 @@ pub(crate) mod dep_node;
mod dep_node_key;
mod edges;
mod graph;
mod query;
mod retained;
mod serialized;

/// Describes the contents of the fingerprint generated by a given query.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,60 @@ use rustc_index::IndexVec;

use super::{DepNode, DepNodeIndex};

pub struct DepGraphQuery {
pub graph: LinkedGraph<DepNode, ()>,
/// An in-memory copy of the current session's query dependency graph, which
/// is only enabled when `-Zquery-dep-graph` is set (for debugging/testing).
///
/// Normally, dependencies recorded during the current session are written to
/// disk and then forgotten, to avoid wasting memory on information that is
/// not needed when the compiler is working correctly.
pub struct RetainedDepGraph {
pub inner: LinkedGraph<DepNode, ()>,
pub indices: FxHashMap<DepNode, NodeIndex>,
pub dep_index_to_index: IndexVec<DepNodeIndex, Option<NodeIndex>>,
}

impl DepGraphQuery {
pub fn new(prev_node_count: usize) -> DepGraphQuery {
impl RetainedDepGraph {
pub fn new(prev_node_count: usize) -> Self {
let node_count = prev_node_count + prev_node_count / 4;
let edge_count = 6 * node_count;

let graph = LinkedGraph::with_capacity(node_count, edge_count);
let inner = LinkedGraph::with_capacity(node_count, edge_count);
let indices = FxHashMap::default();
let dep_index_to_index = IndexVec::new();

DepGraphQuery { graph, indices, dep_index_to_index }
Self { inner, indices, dep_index_to_index }
}

pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex]) {
let source = self.graph.add_node(node);
let source = self.inner.add_node(node);
self.dep_index_to_index.insert(index, source);
self.indices.insert(node, source);

for &target in edges.iter() {
// We may miss the edges that are pushed while the `DepGraphQuery` is being accessed.
// Skip them to issues.
if let Some(&Some(target)) = self.dep_index_to_index.get(target) {
self.graph.add_edge(source, target, ());
self.inner.add_edge(source, target, ());
}
}
}

pub fn nodes(&self) -> Vec<&DepNode> {
self.graph.all_nodes().iter().map(|n| &n.data).collect()
self.inner.all_nodes().iter().map(|n| &n.data).collect()
}

pub fn edges(&self) -> Vec<(&DepNode, &DepNode)> {
self.graph
self.inner
.all_edges()
.iter()
.map(|edge| (edge.source(), edge.target()))
.map(|(s, t)| (self.graph.node_data(s), self.graph.node_data(t)))
.map(|(s, t)| (self.inner.node_data(s), self.inner.node_data(t)))
.collect()
}

fn reachable_nodes(&self, node: &DepNode, direction: Direction) -> Vec<&DepNode> {
if let Some(&index) = self.indices.get(node) {
self.graph.depth_traverse(index, direction).map(|s| self.graph.node_data(s)).collect()
self.inner.depth_traverse(index, direction).map(|s| self.inner.node_data(s)).collect()
} else {
vec![]
}
Expand Down
Loading
Loading