about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src/graph
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2025-01-20 15:54:51 +0100
committerGitHub <noreply@github.com>2025-01-20 15:54:51 +0100
commit470ab13c5c28a42e706ee8cee92e44257065324f (patch)
treeea612d81208c7fa15d3477ca173d9fe6a18ccc83 /compiler/rustc_data_structures/src/graph
parent1b5b0515f9c12ea8181deec0d9997fe9af6ab417 (diff)
parent1e0204beae7c0ebc5cddc64d1375bc7ee95f41db (diff)
downloadrust-470ab13c5c28a42e706ee8cee92e44257065324f.tar.gz
rust-470ab13c5c28a42e706ee8cee92e44257065324f.zip
Merge pull request #2215 from Kobzol/pull
rustc pull
Diffstat (limited to 'compiler/rustc_data_structures/src/graph')
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/mod.rs8
-rw-r--r--compiler/rustc_data_structures/src/graph/iterate/mod.rs24
-rw-r--r--compiler/rustc_data_structures/src/graph/mod.rs1
-rw-r--r--compiler/rustc_data_structures/src/graph/reversed.rs42
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)
+    }
+}