Rollup merge of #152844 - Zalathar:retain-dep-graph, r=JonathanBrouwer

Rename `DepGraphQuery` to `RetainedDepGraph`

This is a revised subset of https://github.com/rust-lang/rust/pull/152836 that only performs an internal renaming, and does not touch the `-Zquery-dep-graph` flag.

The new name and comments for `RetainedDepGraph` should hopefully do a better job of communicating that it is not used in normal compiler operation, even in incremental mode.
This commit is contained in:
Jonathan Brouwer
2026-02-20 13:24:57 +01:00
committed by GitHub
5 changed files with 85 additions and 78 deletions
@@ -44,7 +44,7 @@
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};
@@ -57,7 +57,7 @@
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 {
@@ -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 {
@@ -202,7 +202,7 @@ 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") {
@@ -210,13 +210,13 @@ fn dump_graph(query: &DepGraphQuery) {
// 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:
@@ -279,51 +279,51 @@ fn node_label(&self, n: &DepKind) -> dot::LabelText<'_> {
// 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);
}
@@ -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
@@ -352,27 +352,27 @@ enum State {
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,
@@ -388,8 +388,8 @@ fn recurse(query: &DepGraphQuery, node_states: &mut [State], node: NodeIndex) ->
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;
}
}
@@ -405,8 +405,8 @@ fn recurse(query: &DepGraphQuery, node_states: &mut [State], node: NodeIndex) ->
}
}
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))
+3 -3
View File
@@ -21,7 +21,7 @@
#[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;
@@ -191,9 +191,9 @@ pub fn is_fully_enabled(&self) -> bool {
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)
}
}
+2 -2
View File
@@ -10,7 +10,7 @@
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;
@@ -21,7 +21,7 @@
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.
@@ -4,26 +4,32 @@
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);
@@ -31,27 +37,27 @@ pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex
// 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![]
}
@@ -59,7 +59,7 @@
use tracing::{debug, instrument};
use super::graph::{CurrentDepGraph, DepNodeColorMap};
use super::query::DepGraphQuery;
use super::retained::RetainedDepGraph;
use super::{DepKind, DepNode, DepNodeIndex};
use crate::dep_graph::edges::EdgesVec;
@@ -615,21 +615,21 @@ fn record(
index: DepNodeIndex,
edge_count: usize,
edges: impl FnOnce(&Self) -> Vec<DepNodeIndex>,
record_graph: &Option<Lock<DepGraphQuery>>,
retained_graph: &Option<Lock<RetainedDepGraph>>,
local: &mut LocalEncoderState,
) {
local.kind_stats[node.kind.as_usize()] += 1;
local.edge_count += edge_count;
if let Some(record_graph) = &record_graph {
if let Some(retained_graph) = &retained_graph {
// Call `edges` before the outlined code to allow the closure to be optimized out.
let edges = edges(self);
// Outline the build of the full dep graph as it's typically disabled and cold.
outline(move || {
// Do not ICE when a query is called from within `with_query`.
if let Some(record_graph) = &mut record_graph.try_lock() {
record_graph.push(index, *node, &edges);
if let Some(retained_graph) = &mut retained_graph.try_lock() {
retained_graph.push(index, *node, &edges);
}
});
}
@@ -662,7 +662,7 @@ fn encode_node(
&self,
index: DepNodeIndex,
node: &NodeInfo,
record_graph: &Option<Lock<DepGraphQuery>>,
retained_graph: &Option<Lock<RetainedDepGraph>>,
local: &mut LocalEncoderState,
) {
node.encode(&mut local.encoder, index);
@@ -672,7 +672,7 @@ fn encode_node(
index,
node.edges.len(),
|_| node.edges[..].to_vec(),
record_graph,
retained_graph,
&mut *local,
);
}
@@ -688,7 +688,7 @@ fn encode_promoted_node(
&self,
index: DepNodeIndex,
prev_index: SerializedDepNodeIndex,
record_graph: &Option<Lock<DepGraphQuery>>,
retained_graph: &Option<Lock<RetainedDepGraph>>,
colors: &DepNodeColorMap,
local: &mut LocalEncoderState,
) {
@@ -714,7 +714,7 @@ fn encode_promoted_node(
.map(|i| colors.current(i).unwrap())
.collect()
},
record_graph,
retained_graph,
&mut *local,
);
}
@@ -845,7 +845,8 @@ fn print_incremental_info(
pub(crate) struct GraphEncoder {
profiler: SelfProfilerRef,
status: EncoderState,
record_graph: Option<Lock<DepGraphQuery>>,
/// In-memory copy of the dep graph; only present if `-Zquery-dep-graph` is set.
retained_graph: Option<Lock<RetainedDepGraph>>,
}
impl GraphEncoder {
@@ -855,18 +856,18 @@ pub(crate) fn new(
prev_node_count: usize,
previous: Arc<SerializedDepGraph>,
) -> Self {
let record_graph = sess
let retained_graph = sess
.opts
.unstable_opts
.query_dep_graph
.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
.then(|| Lock::new(RetainedDepGraph::new(prev_node_count)));
let status = EncoderState::new(encoder, sess.opts.unstable_opts.incremental_info, previous);
GraphEncoder { status, record_graph, profiler: sess.prof.clone() }
GraphEncoder { status, retained_graph, profiler: sess.prof.clone() }
}
pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
if let Some(record_graph) = &self.record_graph {
f(&record_graph.lock())
pub(crate) fn with_retained_dep_graph(&self, f: impl Fn(&RetainedDepGraph)) {
if let Some(retained_graph) = &self.retained_graph {
f(&retained_graph.lock())
}
}
@@ -882,7 +883,7 @@ pub(crate) fn send_new(
let mut local = self.status.local.borrow_mut();
let index = self.status.next_index(&mut *local);
self.status.bump_index(&mut *local);
self.status.encode_node(index, &node, &self.record_graph, &mut *local);
self.status.encode_node(index, &node, &self.retained_graph, &mut *local);
index
}
@@ -914,7 +915,7 @@ pub(crate) fn send_and_color(
}
self.status.bump_index(&mut *local);
self.status.encode_node(index, &node, &self.record_graph, &mut *local);
self.status.encode_node(index, &node, &self.retained_graph, &mut *local);
index
}
@@ -942,7 +943,7 @@ pub(crate) fn send_promoted(
self.status.encode_promoted_node(
index,
prev_index,
&self.record_graph,
&self.retained_graph,
colors,
&mut *local,
);