Merge pull request #1493 from LeandroLP23/refactor/controlflow-shared-helpers

refactor(recompiler): share the control flow helpers
This commit is contained in:
Adrià 2026-10-10 03:03:41 +02:00 committed by GitHub
commit 7703fda15e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 92 deletions

View File

@ -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 <cstdint>
#include <string>
#include <vector>
namespace ShaderRecompiler {
std::string toHexString(std::uint32_t value);
bool contains(const std::vector<std::uint32_t>& values, std::uint32_t value);
std::vector<std::uint32_t> intersectSorted(const std::vector<std::uint32_t>& first, const std::vector<std::uint32_t>& second);
void addUnique(std::vector<std::uint32_t>& values, std::uint32_t value);
void sortUnique(std::vector<std::uint32_t>& values);
std::uint32_t remapId(std::uint32_t id, const std::vector<std::uint32_t>& idMap);
void remapIds(std::vector<std::uint32_t>& values, const std::vector<std::uint32_t>& idMap);
void rebuildPredecessors(ControlFlowGraph& graph);
}
#endif

View File

@ -1,4 +1,5 @@
#include "ControlFlow/ControlFlowGraph.hpp"
#include "ControlFlow/ControlFlowHelpers.hpp"
#include <algorithm>
#include <cstdio>
#include <iterator>
@ -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<std::uint32_t> intersectSorted(const std::vector<std::uint32_t>& fir
return result;
}
void addUnique(std::vector<std::uint32_t>& values, std::uint32_t value) {
if (std::find(values.begin(), values.end(), value) == values.end()) {
values.push_back(value);
}
}
void sortUnique(std::vector<std::uint32_t>& 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<std::uint32_t>& idMap) {
return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id;
}
void remapIds(std::vector<std::uint32_t>& values, const std::vector<std::uint32_t>& 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<std::uint32_t>& values) {
std::string text;
for (std::size_t i = 0; i < values.size(); ++i) {

View File

@ -1,4 +1,5 @@
#include "ControlFlow/GraphBuilder.hpp"
#include "ControlFlow/ControlFlowHelpers.hpp"
#include <algorithm>
#include <bit>
#include <cstdio>
@ -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<std::uint32_t>& values, std::uint32_t value) {
if (std::find(values.begin(), values.end(), value) == values.end()) {
values.push_back(value);
}
}
void sortUnique(std::vector<std::uint32_t>& 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<std::uint32_t>& idMap) {
return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id;
}
void remapIds(std::vector<std::uint32_t>& values, const std::vector<std::uint32_t>& 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<int>(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");

View File

@ -1,4 +1,5 @@
#include "ControlFlow/Structurizer.hpp"
#include "ControlFlow/ControlFlowHelpers.hpp"
#include <algorithm>
#include <functional>
#include <iterator>
@ -19,27 +20,6 @@ std::vector<std::uint32_t> allBlockIds(std::uint32_t count) {
return ids;
}
std::vector<std::uint32_t> intersectSorted(const std::vector<std::uint32_t>& first, const std::vector<std::uint32_t>& second) {
std::vector<std::uint32_t> result;
std::set_intersection(first.begin(), first.end(), second.begin(), second.end(), std::back_inserter(result));
return result;
}
void sortUnique(std::vector<std::uint32_t>& values) {
std::sort(values.begin(), values.end());
values.erase(std::unique(values.begin(), values.end()), values.end());
}
void addUnique(std::vector<std::uint32_t>& values, std::uint32_t value) {
if (std::find(values.begin(), values.end(), value) == values.end()) {
values.push_back(value);
}
}
bool contains(const std::vector<std::uint32_t>& values, std::uint32_t value) {
return std::find(values.begin(), values.end(), value) != values.end();
}
bool replaceValue(std::vector<std::uint32_t>& 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<std::uint32_t>& idMap) {
return id != InvalidControlFlowId && id < idMap.size() ? idMap[id] : id;
}
void remapIds(std::vector<std::uint32_t>& values, const std::vector<std::uint32_t>& 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<std::uint32_t> applyBlockOrder(ControlFlowGraph& graph, std::vector<BasicBlock> blocks) {
std::vector<std::uint32_t> idMap(blocks.size(), InvalidControlFlowId);
for (std::uint32_t i = 0; i < blocks.size(); ++i) {