diff --git a/src/compiler/rust/depth_first_search.rs b/src/compiler/rust/depth_first_search.rs new file mode 100644 index 00000000000..f067be00711 --- /dev/null +++ b/src/compiler/rust/depth_first_search.rs @@ -0,0 +1,54 @@ +// Copyright © 2025 Collabora, Ltd. +// SPDX-License-Identifier: MIT + +use crate::bitset::BitSet; + +/// A trait implementing a depth-first search over a graph +pub trait DepthFirstSearch { + type ChildIter; + + /// Pre-visit a node. This is called before any children or edges are + /// visited. Returns an iterator to this node's children in the graph. + fn pre(&mut self, id: usize) -> Self::ChildIter; + + /// Visit an edge. An edge is visited before the child at the end of that + /// edge is pre-visited. Every edge is visited, even if if the node this + /// edge points to has already been visited. + fn edge(&mut self, _parent: usize, _child: usize) { + // Does nothing by default + } + + /// Post-visit a node. This is called after all the children have been + /// visited. + fn post(&mut self, _id: usize) { + // Does nothing by default + } +} + +fn dfs_impl(dfs: &mut D, seen: &mut BitSet, id: usize) +where + I: Iterator, + D: DepthFirstSearch, +{ + if seen.contains(id) { + return; + } + + seen.insert(id); + + let children = dfs.pre(id); + for child in children { + dfs.edge(id, child); + dfs_impl(dfs, seen, child); + } + dfs.post(id); +} + +pub fn dfs(dfs: &mut D, start: usize) +where + I: Iterator, + D: DepthFirstSearch, +{ + let mut seen = BitSet::new(); + dfs_impl(dfs, &mut seen, start); +} diff --git a/src/compiler/rust/lib.rs b/src/compiler/rust/lib.rs index c7d559b151f..68b0087f18b 100644 --- a/src/compiler/rust/lib.rs +++ b/src/compiler/rust/lib.rs @@ -6,6 +6,7 @@ pub mod bindings; pub mod bitset; pub mod cfg; pub mod dataflow; +pub mod depth_first_search; pub mod memstream; pub mod nir; pub mod nir_instr_printer; diff --git a/src/compiler/rust/meson.build b/src/compiler/rust/meson.build index 4f0aae835ca..244fb00e1a4 100644 --- a/src/compiler/rust/meson.build +++ b/src/compiler/rust/meson.build @@ -6,6 +6,7 @@ _compiler_rs_sources = [ 'bitset.rs', 'cfg.rs', 'dataflow.rs', + 'depth_first_search.rs', 'memstream.rs', 'nir_instr_printer.rs', 'nir.rs',