diff --git a/core/shader/recompiler/ControlFlow/include/ControlFlow/ControlFlowHelpers.hpp b/core/shader/recompiler/ControlFlow/include/ControlFlow/ControlFlowHelpers.hpp new file mode 100644 index 000000000..ced80a638 --- /dev/null +++ b/core/shader/recompiler/ControlFlow/include/ControlFlow/ControlFlowHelpers.hpp @@ -0,0 +1,22 @@ +#ifndef CORE_SHADER_RECOMPILIER_CONTROLFLOW_INCLUDE_CONTROLFLOW_CONTROLFLOWHELPERS_HPP +#define CORE_SHADER_RECOMPILIER_CONTROLFLOW_INCLUDE_CONTROLFLOW_CONTROLFLOWHELPERS_HPP + +#include "ControlFlow/ControlFlowGraph.hpp" +#include +#include +#include + +namespace ShaderRecompiler { + +std::string toHexString(std::uint32_t value); +bool contains(const std::vector& values, std::uint32_t value); +std::vector intersectSorted(const std::vector& first, const std::vector& second); +void addUnique(std::vector& values, std::uint32_t value); +void sortUnique(std::vector& values); +std::uint32_t remapId(std::uint32_t id, const std::vector& idMap); +void remapIds(std::vector& values, const std::vector& idMap); +void rebuildPredecessors(ControlFlowGraph& graph); + +} + +#endif diff --git a/core/shader/recompiler/ControlFlow/src/ControlFlowGraph.cpp b/core/shader/recompiler/ControlFlow/src/ControlFlowGraph.cpp index 12ebb915d..a0894ce95 100644 --- a/core/shader/recompiler/ControlFlow/src/ControlFlowGraph.cpp +++ b/core/shader/recompiler/ControlFlow/src/ControlFlowGraph.cpp @@ -1,4 +1,5 @@ #include "ControlFlow/ControlFlowGraph.hpp" +#include "ControlFlow/ControlFlowHelpers.hpp" #include #include #include @@ -7,8 +8,6 @@ namespace ShaderRecompiler { -namespace { - std::string toHexString(std::uint32_t value) { char buffer[11]; std::snprintf(buffer, sizeof(buffer), "0x%08x", value); @@ -25,6 +24,45 @@ std::vector intersectSorted(const std::vector& fir return result; } +void addUnique(std::vector& values, std::uint32_t value) { + if (std::find(values.begin(), values.end(), value) == values.end()) { + values.push_back(value); + } +} + +void sortUnique(std::vector& values) { + std::sort(values.begin(), values.end()); + values.erase(std::unique(values.begin(), values.end()), values.end()); +} + +std::uint32_t remapId(std::uint32_t id, const std::vector& idMap) { + return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id; +} + +void remapIds(std::vector& values, const std::vector& idMap) { + for (auto& value : values) { + value = remapId(value, idMap); + } + sortUnique(values); +} + +void rebuildPredecessors(ControlFlowGraph& graph) { + for (auto& block : graph.blocks) { + block.predecessors.clear(); + sortUnique(block.successors); + } + for (const auto& block : graph.blocks) { + for (const auto successor : block.successors) { + addUnique(graph.blocks[successor].predecessors, block.id); + } + } + for (auto& block : graph.blocks) { + sortUnique(block.predecessors); + } +} + +namespace { + std::string joinIds(const std::vector& values) { std::string text; for (std::size_t i = 0; i < values.size(); ++i) { diff --git a/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp b/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp index 1bd3c7776..55067d748 100644 --- a/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp +++ b/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp @@ -1,4 +1,5 @@ #include "ControlFlow/GraphBuilder.hpp" +#include "ControlFlow/ControlFlowHelpers.hpp" #include #include #include @@ -12,38 +13,10 @@ namespace ShaderRecompiler { namespace { -std::string toHexString(std::uint32_t value) { - char buffer[11]; - std::snprintf(buffer, sizeof(buffer), "0x%08x", value); - return std::string(buffer); -} - std::uint32_t instructionEndProgramCounter(const RdnaInstruction& instruction) { return instruction.programCounter + instruction.wordCount * 4u; } -void addUnique(std::vector& values, std::uint32_t value) { - if (std::find(values.begin(), values.end(), value) == values.end()) { - values.push_back(value); - } -} - -void sortUnique(std::vector& values) { - std::sort(values.begin(), values.end()); - values.erase(std::unique(values.begin(), values.end()), values.end()); -} - -std::uint32_t remapId(std::uint32_t id, const std::vector& idMap) { - return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id; -} - -void remapIds(std::vector& values, const std::vector& idMap) { - for (auto& value : values) { - value = remapId(value, idMap); - } - sortUnique(values); -} - std::uint32_t estimatedSpirvWords(const RdnaInstruction& instruction) { switch (instruction.op) { case RdnaOpcode::VReadfirstlaneB32: @@ -641,21 +614,6 @@ BranchCondition conditionForOpcode(RdnaOpcode opcode) { throw std::logic_error("unreachable branch condition for opcode " + std::to_string(static_cast(opcode))); } -void rebuildPredecessors(ControlFlowGraph& graph) { - for (auto& block : graph.blocks) { - block.predecessors.clear(); - sortUnique(block.successors); - } - for (const auto& block : graph.blocks) { - for (const auto successor : block.successors) { - addUnique(graph.blocks[successor].predecessors, block.id); - } - } - for (auto& block : graph.blocks) { - sortUnique(block.predecessors); - } -} - void pruneUnreachableBlocks(ControlFlowGraph& graph) { if (graph.entryBlock >= graph.blocks.size()) { throw std::invalid_argument("control flow graph entry block is out of range"); diff --git a/core/shader/recompiler/ControlFlow/src/Structurizer.cpp b/core/shader/recompiler/ControlFlow/src/Structurizer.cpp index f23bd9258..adc933239 100644 --- a/core/shader/recompiler/ControlFlow/src/Structurizer.cpp +++ b/core/shader/recompiler/ControlFlow/src/Structurizer.cpp @@ -1,4 +1,5 @@ #include "ControlFlow/Structurizer.hpp" +#include "ControlFlow/ControlFlowHelpers.hpp" #include #include #include @@ -19,27 +20,6 @@ std::vector allBlockIds(std::uint32_t count) { return ids; } -std::vector intersectSorted(const std::vector& first, const std::vector& second) { - std::vector result; - std::set_intersection(first.begin(), first.end(), second.begin(), second.end(), std::back_inserter(result)); - return result; -} - -void sortUnique(std::vector& values) { - std::sort(values.begin(), values.end()); - values.erase(std::unique(values.begin(), values.end()), values.end()); -} - -void addUnique(std::vector& values, std::uint32_t value) { - if (std::find(values.begin(), values.end(), value) == values.end()) { - values.push_back(value); - } -} - -bool contains(const std::vector& values, std::uint32_t value) { - return std::find(values.begin(), values.end(), value) != values.end(); -} - bool replaceValue(std::vector& values, std::uint32_t oldValue, std::uint32_t newValue) { bool changed = false; for (auto& value : values) { @@ -73,32 +53,6 @@ bool replaceTerminatorTarget(Terminator& terminator, std::uint32_t oldValue, std return changed; } -std::uint32_t remapId(std::uint32_t id, const std::vector& idMap) { - return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id; -} - -void remapIds(std::vector& values, const std::vector& idMap) { - for (auto& value : values) { - value = remapId(value, idMap); - } - sortUnique(values); -} - -void rebuildPredecessors(ControlFlowGraph& graph) { - for (auto& block : graph.blocks) { - block.predecessors.clear(); - sortUnique(block.successors); - } - for (const auto& block : graph.blocks) { - for (const auto successor : block.successors) { - addUnique(graph.blocks[successor].predecessors, block.id); - } - } - for (auto& block : graph.blocks) { - sortUnique(block.predecessors); - } -} - std::vector applyBlockOrder(ControlFlowGraph& graph, std::vector blocks) { std::vector idMap(blocks.size(), InvalidControlFlowId); for (std::uint32_t i = 0; i < blocks.size(); ++i) {