diff --git a/src/passes/GlobalEffects.cpp b/src/passes/GlobalEffects.cpp index 7f47cf108eb..41e1dffedc7 100644 --- a/src/passes/GlobalEffects.cpp +++ b/src/passes/GlobalEffects.cpp @@ -22,6 +22,7 @@ #include "ir/effects.h" #include "ir/module-utils.h" #include "pass.h" +#include "support/graph_traversal.h" #include "support/strongly_connected_components.h" #include "wasm.h" diff --git a/src/support/graph_traversal.h b/src/support/graph_traversal.h new file mode 100644 index 00000000000..7da0f780587 --- /dev/null +++ b/src/support/graph_traversal.h @@ -0,0 +1,72 @@ +/* + * Copyright 2026 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +namespace wasm { + +template + requires std:: + invocable&, const T&> + class Graph { +public: + template Sen> + requires std::convertible_to, T> + Graph(It rootsBegin, Sen rootsEnd, auto&& successors) + : roots(rootsBegin, rootsEnd), + successors(std::forward(successors)) {} + + // Traverse the graph depth-first, calling `successors` exactly once for each + // node (unless the node appears multiple times in `roots`). Return the set of + // nodes visited. + std::unordered_set traverseDepthFirst() const { + std::vector stack(roots.begin(), roots.end()); + std::unordered_set visited(roots.begin(), roots.end()); + + while (!stack.empty()) { + auto curr = std::move(stack.back()); + stack.pop_back(); + + auto maybePush = [&](const T& t) { + if (visited.contains(t)) { + return; + } + + visited.insert(t); + stack.push_back(t); + }; + + successors(maybePush, curr); + } + + return visited; + } + +private: + std::vector roots; + SuccessorFunction successors; +}; + +template Sen, + typename SuccessorFunction> +Graph(It, Sen, SuccessorFunction) + -> Graph, std::decay_t>; + +} // namespace wasm