Skip to content

Commit ddde5c6

Browse files
committed
Remove FrozenLinkedGraph
1 parent 12030f8 commit ddde5c6

7 files changed

Lines changed: 73 additions & 125 deletions

File tree

compiler/rustc_data_structures/src/graph/linked_graph/mod.rs

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
//! be indexed by the direction (see the type `Direction`).
2222
2323
use std::fmt::Debug;
24-
use std::mem;
25-
use std::ops::Deref;
2624

2725
use rustc_index::bit_set::DenseBitSet;
2826
use rustc_index::{Idx, IndexVec};
@@ -47,32 +45,18 @@ mod tests;
4745
/// This graph implementation predates the later [graph traits](crate::graph),
4846
/// and does not implement those traits, so it has its own implementations of a
4947
/// few basic graph algorithms.
50-
#[derive(Clone)]
5148
pub struct LinkedGraph<I: Idx, N, E> {
5249
nodes: IndexVec<I, Option<Node<N>>>,
5350
edges: Vec<Edge<I, E>>,
51+
linked_edges: usize,
5452
}
5553

56-
#[derive(Clone)]
57-
pub struct FrozenLinkedGraph<I: Idx, N, E> {
58-
inner: LinkedGraph<I, N, E>,
59-
}
60-
61-
impl<I: Idx, N, E> Deref for FrozenLinkedGraph<I, N, E> {
62-
type Target = LinkedGraph<I, N, E>;
63-
64-
fn deref(&self) -> &Self::Target {
65-
&self.inner
66-
}
67-
}
68-
69-
#[derive(Clone)]
7054
pub struct Node<N> {
7155
first_edge: [EdgeIndex; 2], // see module comment
7256
pub data: N,
7357
}
7458

75-
#[derive(Debug, Clone)]
59+
#[derive(Debug)]
7660
pub struct Edge<I, E> {
7761
next_edge: [EdgeIndex; 2], // see module comment
7862
source: I,
@@ -97,18 +81,26 @@ pub const INCOMING: Direction = Direction { repr: 1 };
9781

9882
impl<I: Idx, N, E> LinkedGraph<I, N, E> {
9983
pub fn new() -> Self {
100-
Self { nodes: IndexVec::new(), edges: Vec::new() }
84+
Self { nodes: IndexVec::new(), edges: Vec::new(), linked_edges: 0 }
10185
}
10286

10387
pub fn from_node_n(data: N, n: usize) -> Self
10488
where
10589
N: Copy,
10690
{
107-
Self { nodes: IndexVec::from_fn_n(|_| Some(Node::new(data)), n), edges: Vec::new() }
91+
Self {
92+
nodes: IndexVec::from_fn_n(|_| Some(Node::new(data)), n),
93+
edges: Vec::new(),
94+
linked_edges: 0,
95+
}
10896
}
10997

11098
pub fn with_capacity(nodes: usize, edges: usize) -> Self {
111-
Self { nodes: IndexVec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
99+
Self {
100+
nodes: IndexVec::with_capacity(nodes),
101+
edges: Vec::with_capacity(edges),
102+
linked_edges: 0,
103+
}
112104
}
113105

114106
// # Simple accessors
@@ -152,10 +144,6 @@ impl<I: Idx, N, E> LinkedGraph<I, N, E> {
152144
self.nodes[idx].as_ref().unwrap()
153145
}
154146

155-
pub fn node_mut(&mut self, idx: I) -> &mut Node<N> {
156-
self.nodes[idx].as_mut().unwrap()
157-
}
158-
159147
// # Edge construction and queries
160148

161149
pub fn next_edge_index(&self) -> EdgeIndex {
@@ -186,49 +174,32 @@ impl<I: Idx, N, E> LinkedGraph<I, N, E> {
186174
self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge))
187175
}
188176

189-
fn generate_lists(&mut self) {
190-
for (idx, edge) in self.edges.iter_mut().enumerate() {
191-
// read and adjust current first of the list of edges from each node
192-
let source_first = mem::replace(
193-
&mut self.nodes[edge.source].as_mut().unwrap().first_edge[OUTGOING.repr],
194-
EdgeIndex(idx),
195-
);
196-
let target_first = mem::replace(
197-
&mut self.nodes[edge.target].as_mut().unwrap().first_edge[INCOMING.repr],
198-
EdgeIndex(idx),
199-
);
177+
fn link_edges(&mut self) {
178+
for (idx, edge) in self.edges.iter_mut().enumerate().skip(self.linked_edges) {
179+
// read current first of the list of edges from each node
180+
let (Some(Some(source_node)), Some(Some(target_node))) =
181+
(self.nodes.get(edge.source), self.nodes.get(edge.target))
182+
else {
183+
return;
184+
};
185+
let source_first = source_node.first_edge[OUTGOING.repr];
186+
let target_first = target_node.first_edge[INCOMING.repr];
187+
self.linked_edges += 1;
200188

201-
// populate edges lists, with the previous firsts from each node
189+
// create the new edge, with the previous firsts from each node
202190
// as the next pointers
203191
edge.next_edge = [source_first, target_first];
204-
}
205-
}
206192

207-
pub fn freeze(mut self) -> FrozenLinkedGraph<I, N, E> {
208-
self.generate_lists();
209-
FrozenLinkedGraph { inner: self }
210-
}
211-
}
212-
213-
impl<I: Idx, N: Debug, E: Debug> LinkedGraph<I, N, E> {
214-
pub fn add_edge(&mut self, source: I, target: I, data: E) -> EdgeIndex {
215-
debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);
216-
217-
let idx = self.next_edge_index();
218-
self.edges.push(Edge {
219-
next_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
220-
source,
221-
target,
222-
data,
223-
});
224-
idx
193+
// adjust the firsts for each node target be the next object.
194+
self.nodes[edge.source].as_mut().unwrap().first_edge[OUTGOING.repr] = EdgeIndex(idx);
195+
self.nodes[edge.target].as_mut().unwrap().first_edge[INCOMING.repr] = EdgeIndex(idx);
196+
}
225197
}
226-
}
227198

228-
impl<I: Idx, N, E> FrozenLinkedGraph<I, N, E> {
229199
pub fn adjacent_edges(&self, source: I, direction: Direction) -> AdjacentEdges<'_, I, N, E> {
230-
let first_edge = self.inner.node(source).first_edge[direction.repr];
231-
AdjacentEdges { graph: &self.inner, direction, next: first_edge }
200+
assert_eq!(self.linked_edges, self.edges.len(), "linked graph is incomplete");
201+
let first_edge = self.node(source).first_edge[direction.repr];
202+
AdjacentEdges { graph: &self, direction, next: first_edge }
232203
}
233204

234205
pub fn outgoing_edges(&self, source: I) -> AdjacentEdges<'_, I, N, E> {
@@ -288,6 +259,22 @@ impl<I: Idx, N, E> FrozenLinkedGraph<I, N, E> {
288259
}
289260
}
290261

262+
impl<I: Idx, N: Debug, E: Debug> LinkedGraph<I, N, E> {
263+
pub fn add_edge(&mut self, source: I, target: I, data: E) -> EdgeIndex {
264+
debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);
265+
266+
let idx = self.next_edge_index();
267+
self.edges.push(Edge {
268+
next_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
269+
source,
270+
target,
271+
data,
272+
});
273+
self.link_edges();
274+
idx
275+
}
276+
}
277+
291278
impl<N> Node<N> {
292279
#[inline]
293280
const fn new(data: N) -> Node<N> {
@@ -334,15 +321,15 @@ impl<'g, I: Idx, N, E> Iterator for AdjacentEdges<'g, I, N, E> {
334321
}
335322

336323
pub struct DepthFirstTraversal<'g, I: Idx, N, E> {
337-
graph: &'g FrozenLinkedGraph<I, N, E>,
324+
graph: &'g LinkedGraph<I, N, E>,
338325
stack: Vec<I>,
339326
visited: DenseBitSet<usize>,
340327
direction: Direction,
341328
}
342329

343330
impl<'g, I: Idx, N, E> DepthFirstTraversal<'g, I, N, E> {
344331
pub fn with_start_node(
345-
graph: &'g FrozenLinkedGraph<I, N, E>,
332+
graph: &'g LinkedGraph<I, N, E>,
346333
start_node: I,
347334
direction: Direction,
348335
) -> Self {

compiler/rustc_data_structures/src/graph/linked_graph/tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use rustc_index::Idx;
22
use tracing::debug;
33

4-
use super::{Debug, FrozenLinkedGraph, LinkedGraph};
4+
use super::{Debug, LinkedGraph};
55

6-
type TestGraph = FrozenLinkedGraph<usize, &'static str, &'static str>;
6+
type TestGraph = LinkedGraph<usize, &'static str, &'static str>;
77

88
fn create_graph() -> TestGraph {
99
let mut graph = LinkedGraph::new();
@@ -38,7 +38,7 @@ fn create_graph() -> TestGraph {
3838
graph.add_edge(e, c, "EC");
3939
graph.add_edge(f, b, "FB");
4040

41-
return graph.freeze();
41+
graph
4242
}
4343

4444
#[test]
@@ -63,7 +63,7 @@ fn each_edge() {
6363
}
6464

6565
fn test_adjacent_edges<I: Idx, N: PartialEq + Debug, E: PartialEq + Debug>(
66-
graph: &FrozenLinkedGraph<I, N, E>,
66+
graph: &LinkedGraph<I, N, E>,
6767
start_index: I,
6868
start_data: N,
6969
expected_incoming: &[(E, N)],

compiler/rustc_incremental/src/assert_dep_graph.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
4343
use rustc_hir::intravisit::{self, Visitor};
4444
use rustc_index::IndexVec;
4545
use rustc_middle::dep_graph::{
46-
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, DepNodeIndex, EdgeFilter,
47-
FrozenDepGraphQuery, dep_kinds,
46+
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, DepNodeIndex, EdgeFilter, dep_kinds,
4847
};
4948
use rustc_middle::hir::nested_filter;
5049
use rustc_middle::ty::TyCtxt;
@@ -210,7 +209,6 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
210209
return;
211210
}
212211
tcx.dep_graph.with_query(|query| {
213-
let query = query.clone().freeze();
214212
for &(_, source_def_id, ref source_dep_node) in if_this_changed {
215213
let dependents = query.transitive_predecessors(source_dep_node);
216214
for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need {
@@ -231,20 +229,18 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
231229
fn dump_graph(query: &DepGraphQuery) {
232230
let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| "dep_graph".to_string());
233231

234-
let query = query.clone().freeze();
235-
236232
let nodes = match env::var("RUST_DEP_GRAPH_FILTER") {
237233
Ok(string) => {
238234
// Expect one of: "-> target", "source -> target", or "source ->".
239235
let edge_filter =
240236
EdgeFilter::new(&string).unwrap_or_else(|e| bug!("invalid filter: {}", e));
241-
let sources = node_set(&query, &edge_filter.source);
242-
let targets = node_set(&query, &edge_filter.target);
243-
filter_nodes(&query, &sources, &targets)
237+
let sources = node_set(query, &edge_filter.source);
238+
let targets = node_set(query, &edge_filter.target);
239+
filter_nodes(query, &sources, &targets)
244240
}
245241
Err(_) => query.nodes().into_iter().map(|n| n.kind).collect(),
246242
};
247-
let edges = filter_edges(&query, &nodes);
243+
let edges = filter_edges(query, &nodes);
248244

249245
{
250246
// dump a .txt file with just the edges:
@@ -308,7 +304,7 @@ impl<'a> dot::Labeller<'a> for GraphvizDepGraph {
308304
// filter) or the set of nodes whose labels contain all of those
309305
// substrings.
310306
fn node_set<'q>(
311-
query: &'q FrozenDepGraphQuery,
307+
query: &'q DepGraphQuery,
312308
filter: &DepNodeFilter,
313309
) -> Option<FxIndexSet<&'q DepNode>> {
314310
debug!("node_set(filter={:?})", filter);
@@ -321,7 +317,7 @@ fn node_set<'q>(
321317
}
322318

323319
fn filter_nodes<'q>(
324-
query: &'q FrozenDepGraphQuery,
320+
query: &'q DepGraphQuery,
325321
sources: &Option<FxIndexSet<&'q DepNode>>,
326322
targets: &Option<FxIndexSet<&'q DepNode>>,
327323
) -> FxIndexSet<DepKind> {
@@ -339,7 +335,7 @@ fn filter_nodes<'q>(
339335
}
340336

341337
fn walk_nodes<'q>(
342-
query: &'q FrozenDepGraphQuery,
338+
query: &'q DepGraphQuery,
343339
starts: &FxIndexSet<&'q DepNode>,
344340
direction: Direction,
345341
) -> FxIndexSet<DepKind> {
@@ -363,7 +359,7 @@ fn walk_nodes<'q>(
363359
}
364360

365361
fn walk_between<'q>(
366-
query: &'q FrozenDepGraphQuery,
362+
query: &'q DepGraphQuery,
367363
sources: &FxIndexSet<&'q DepNode>,
368364
targets: &FxIndexSet<&'q DepNode>,
369365
) -> FxIndexSet<DepKind> {
@@ -401,7 +397,7 @@ fn walk_between<'q>(
401397
.collect();
402398

403399
fn recurse(
404-
query: &FrozenDepGraphQuery,
400+
query: &DepGraphQuery,
405401
node_states: &mut IndexVec<DepNodeIndex, State>,
406402
node: DepNodeIndex,
407403
) -> bool {
@@ -437,10 +433,7 @@ fn walk_between<'q>(
437433
}
438434
}
439435

440-
fn filter_edges(
441-
query: &FrozenDepGraphQuery,
442-
nodes: &FxIndexSet<DepKind>,
443-
) -> Vec<(DepKind, DepKind)> {
436+
fn filter_edges(query: &DepGraphQuery, nodes: &FxIndexSet<DepKind>) -> Vec<(DepKind, DepKind)> {
444437
let uniq: FxIndexSet<_> = query
445438
.edges()
446439
.into_iter()

compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
use std::fmt;
44

55
use rustc_data_structures::fx::FxHashSet;
6-
use rustc_data_structures::graph::linked_graph::{
7-
Direction, FrozenLinkedGraph, INCOMING, LinkedGraph, OUTGOING,
8-
};
6+
use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, OUTGOING};
97
use rustc_data_structures::intern::Interned;
108
use rustc_data_structures::unord::UnordSet;
119
use rustc_index::{IndexSlice, IndexVec};
@@ -118,7 +116,7 @@ struct RegionAndOrigin<'tcx> {
118116
origin: SubregionOrigin<'tcx>,
119117
}
120118

121-
type RegionGraph<'tcx> = FrozenLinkedGraph<RegionVid, (), Constraint<'tcx>>;
119+
type RegionGraph<'tcx> = LinkedGraph<RegionVid, (), Constraint<'tcx>>;
122120

123121
struct LexicalResolver<'cx, 'tcx> {
124122
region_rels: &'cx RegionRelations<'cx, 'tcx>,
@@ -671,17 +669,15 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
671669

672670
fn construct_graph(&self) -> RegionGraph<'tcx> {
673671
let num_vars = self.num_vars();
674-
let mut graph = LinkedGraph::from_node_n((), num_vars);
672+
let mut graph = LinkedGraph::from_node_n((), num_vars + 2);
675673

676674
// Issue #30438: two distinct dummy nodes, one for incoming
677675
// edges (dummy_source) and another for outgoing edges
678676
// (dummy_sink). In `dummy -> a -> b -> dummy`, using one
679677
// dummy node leads one to think (erroneously) there exists a
680678
// path from `b` to `a`. Two dummy nodes sidesteps the issue.
681679
let dummy_source = RegionVid::from_usize(num_vars);
682-
graph.add_node(dummy_source, ());
683680
let dummy_sink = RegionVid::from_usize(num_vars + 1);
684-
graph.add_node(dummy_sink, ());
685681

686682
for (c, _) in &self.data.constraints {
687683
match c.kind {
@@ -703,7 +699,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
703699
}
704700
}
705701

706-
graph.freeze()
702+
graph
707703
}
708704

709705
fn collect_error_for_expanding_node(

compiler/rustc_middle/src/dep_graph/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kind_from_label, dep_kinds,
1212
pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata};
1313
pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter};
1414
pub use rustc_query_system::dep_graph::{
15-
DepContext, DepGraphQuery, DepNodeIndex, Deps, FrozenDepGraphQuery, SerializedDepGraph,
16-
SerializedDepNodeIndex, TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result,
15+
DepContext, DepGraphQuery, DepNodeIndex, Deps, SerializedDepGraph, SerializedDepNodeIndex,
16+
TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result,
1717
};
1818

1919
pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepsType>;

compiler/rustc_query_system/src/dep_graph/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::panic;
1010
pub use dep_node::{DepKind, DepKindVTable, DepNode, DepNodeParams, WorkProductId};
1111
pub(crate) use graph::DepGraphData;
1212
pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result};
13-
pub use query::{DepGraphQuery, FrozenDepGraphQuery};
13+
pub use query::DepGraphQuery;
1414
use rustc_data_structures::profiling::SelfProfilerRef;
1515
use rustc_data_structures::sync::DynSync;
1616
use rustc_session::Session;

0 commit comments

Comments
 (0)