[ir] Add non-const DependencyOrderedFunctions()
This enables it to be used from transforms that need to mutate the
outputs.
Change-Id: I092b20b56b7b80b97141d581670a4603fbca3e96
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/188341
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/module.cc b/src/tint/lang/core/ir/module.cc
index a1be474..49af3bb 100644
--- a/src/tint/lang/core/ir/module.cc
+++ b/src/tint/lang/core/ir/module.cc
@@ -40,18 +40,19 @@
namespace {
/// Helper to non-recursively sort a module's function in dependency order.
+template <typename F>
struct FunctionSorter {
/// The dependency-ordered list of functions.
- Vector<const Function*, 16> ordered_functions{};
+ Vector<F*, 16> ordered_functions{};
/// The functions that have been visited and checked for dependencies.
- Hashset<const Function*, 16> visited{};
+ Hashset<F*, 16> visited{};
/// A stack of functions that need to processed and eventually added to the ordered list.
- Vector<const Function*, 16> function_stack{};
+ Vector<F*, 16> function_stack{};
/// Visit a function and check for dependencies, and eventually add it to the ordered list.
/// @param func the function to visit
- void Visit(const Function* func) {
+ void Visit(F* func) {
function_stack.Push(func);
while (!function_stack.IsEmpty()) {
// Visit the next function on the stack, if it hasn't already been visited.
@@ -76,16 +77,17 @@
/// Visit a function body block and look for dependencies.
/// @param block the function body to visit
- void Visit(const Block* block) {
- Vector<const Block*, 64> block_stack;
+ template <typename B>
+ void Visit(B* block) {
+ Vector<B*, 64> block_stack;
block_stack.Push(block);
while (!block_stack.IsEmpty()) {
auto* current_block = block_stack.Pop();
for (auto* inst : *current_block) {
- if (auto* control = inst->As<ControlInstruction>()) {
+ if (auto* control = inst->template As<ControlInstruction>()) {
// Enqueue child blocks.
- control->ForeachBlock([&](const Block* b) { block_stack.Push(b); });
- } else if (auto* call = inst->As<UserCall>()) {
+ control->ForeachBlock([&](B* b) { block_stack.Push(b); });
+ } else if (auto* call = inst->template As<UserCall>()) {
// Enqueue the function that is being called.
if (!visited.Contains(call->Target())) {
function_stack.Push(call->Target());
@@ -94,6 +96,18 @@
}
}
}
+
+ /// Sort the functions of a module.
+ /// @param mod the IR module
+ /// @returns the sorted function list
+ template <typename MOD>
+ static Vector<F*, 16> SortFunctions(MOD& mod) {
+ FunctionSorter<F> sorter;
+ for (auto& func : mod.functions) {
+ sorter.Visit(func.Get());
+ }
+ return std::move(sorter.ordered_functions);
+ }
};
} // namespace
@@ -136,12 +150,12 @@
value_to_name_.Remove(value);
}
+Vector<Function*, 16> Module::DependencyOrderedFunctions() {
+ return FunctionSorter<Function>::SortFunctions(*this);
+}
+
Vector<const Function*, 16> Module::DependencyOrderedFunctions() const {
- FunctionSorter sorter;
- for (auto& func : functions) {
- sorter.Visit(func);
- }
- return std::move(sorter.ordered_functions);
+ return FunctionSorter<const Function>::SortFunctions(*this);
}
} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/module.h b/src/tint/lang/core/ir/module.h
index ebbd0c0..c510de0 100644
--- a/src/tint/lang/core/ir/module.h
+++ b/src/tint/lang/core/ir/module.h
@@ -130,6 +130,8 @@
}
/// @returns the functions in the module, in dependency order
+ Vector<Function*, 16> DependencyOrderedFunctions();
+ /// @returns the functions in the module, in dependency order
Vector<const Function*, 16> DependencyOrderedFunctions() const;
/// The block allocator