diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-01-20 15:54:51 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-20 15:54:51 +0100 |
| commit | 470ab13c5c28a42e706ee8cee92e44257065324f (patch) | |
| tree | ea612d81208c7fa15d3477ca173d9fe6a18ccc83 /compiler/rustc_data_structures/src/graph | |
| parent | 1b5b0515f9c12ea8181deec0d9997fe9af6ab417 (diff) | |
| parent | 1e0204beae7c0ebc5cddc64d1375bc7ee95f41db (diff) | |
| download | rust-470ab13c5c28a42e706ee8cee92e44257065324f.tar.gz rust-470ab13c5c28a42e706ee8cee92e44257065324f.zip | |
Merge pull request #2215 from Kobzol/pull
rustc pull
Diffstat (limited to 'compiler/rustc_data_structures/src/graph')
4 files changed, 64 insertions, 11 deletions
diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs index 43fdfe6ee0d..7724e9347d8 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs @@ -22,7 +22,7 @@ use std::fmt::Debug; -use rustc_index::bit_set::BitSet; +use rustc_index::bit_set::DenseBitSet; use tracing::debug; #[cfg(test)] @@ -214,7 +214,7 @@ impl<N: Debug, E: Debug> Graph<N, E> { direction: Direction, entry_node: NodeIndex, ) -> Vec<NodeIndex> { - let mut visited = BitSet::new_empty(self.len_nodes()); + let mut visited = DenseBitSet::new_empty(self.len_nodes()); let mut stack = vec![]; let mut result = Vec::with_capacity(self.len_nodes()); let mut push_node = |stack: &mut Vec<_>, node: NodeIndex| { @@ -287,7 +287,7 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { pub struct DepthFirstTraversal<'g, N, E> { graph: &'g Graph<N, E>, stack: Vec<NodeIndex>, - visited: BitSet<usize>, + visited: DenseBitSet<usize>, direction: Direction, } @@ -297,7 +297,7 @@ impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> { start_node: NodeIndex, direction: Direction, ) -> Self { - let mut visited = BitSet::new_empty(graph.len_nodes()); + let mut visited = DenseBitSet::new_empty(graph.len_nodes()); visited.insert(start_node.node_id()); DepthFirstTraversal { graph, stack: vec![start_node], visited, direction } } diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index cbc6664d853..7b4573d7a84 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use rustc_index::bit_set::BitSet; +use rustc_index::bit_set::DenseBitSet; use rustc_index::{IndexSlice, IndexVec}; use super::{DirectedGraph, StartNode, Successors}; @@ -78,7 +78,7 @@ where { graph: G, stack: Vec<G::Node>, - visited: BitSet<G::Node>, + visited: DenseBitSet<G::Node>, } impl<G> DepthFirstSearch<G> @@ -86,7 +86,7 @@ where G: DirectedGraph + Successors, { pub fn new(graph: G) -> Self { - Self { stack: vec![], visited: BitSet::new_empty(graph.num_nodes()), graph } + Self { stack: vec![], visited: DenseBitSet::new_empty(graph.num_nodes()), graph } } /// Version of `push_start_node` that is convenient for chained @@ -125,6 +125,16 @@ where pub fn visited(&self, node: G::Node) -> bool { self.visited.contains(node) } + + /// Returns a reference to the set of nodes that have been visited, with + /// the same caveats as [`Self::visited`]. + /// + /// When incorporating the visited nodes into another bitset, using bulk + /// operations like `union` or `intersect` can be more efficient than + /// processing each node individually. + pub fn visited_set(&self) -> &DenseBitSet<G::Node> { + &self.visited + } } impl<G> std::fmt::Debug for DepthFirstSearch<G> @@ -207,8 +217,8 @@ where { graph: &'graph G, stack: Vec<Event<G::Node>>, - visited: BitSet<G::Node>, - settled: BitSet<G::Node>, + visited: DenseBitSet<G::Node>, + settled: DenseBitSet<G::Node>, } impl<'graph, G> TriColorDepthFirstSearch<'graph, G> @@ -219,8 +229,8 @@ where TriColorDepthFirstSearch { graph, stack: vec![], - visited: BitSet::new_empty(graph.num_nodes()), - settled: BitSet::new_empty(graph.num_nodes()), + visited: DenseBitSet::new_empty(graph.num_nodes()), + settled: DenseBitSet::new_empty(graph.num_nodes()), } } diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 103ddd917bf..92035e8bc48 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -4,6 +4,7 @@ pub mod dominators; pub mod implementation; pub mod iterate; mod reference; +pub mod reversed; pub mod scc; pub mod vec_graph; diff --git a/compiler/rustc_data_structures/src/graph/reversed.rs b/compiler/rustc_data_structures/src/graph/reversed.rs new file mode 100644 index 00000000000..9b726deaa15 --- /dev/null +++ b/compiler/rustc_data_structures/src/graph/reversed.rs @@ -0,0 +1,42 @@ +use crate::graph::{DirectedGraph, Predecessors, Successors}; + +/// View that reverses the direction of edges in its underlying graph, so that +/// successors become predecessors and vice-versa. +/// +/// Because of `impl<G: Graph> Graph for &G`, the underlying graph can be +/// wrapped by-reference instead of by-value if desired. +#[derive(Clone, Copy, Debug)] +pub struct ReversedGraph<G> { + pub inner: G, +} + +impl<G> ReversedGraph<G> { + pub fn new(inner: G) -> Self { + Self { inner } + } +} + +impl<G: DirectedGraph> DirectedGraph for ReversedGraph<G> { + type Node = G::Node; + + fn num_nodes(&self) -> usize { + self.inner.num_nodes() + } +} + +// Implementing `StartNode` is not possible in general, because the start node +// of an underlying graph is instead an _end_ node in the reversed graph. +// But would be possible to define another wrapper type that adds an explicit +// start node to its underlying graph, if desired. + +impl<G: Predecessors> Successors for ReversedGraph<G> { + fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> { + self.inner.predecessors(node) + } +} + +impl<G: Successors> Predecessors for ReversedGraph<G> { + fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> { + self.inner.successors(node) + } +} |
