shader: switch canonicalization: fix ordering
Some checks are pending
Formatting check / formatting-check (push) Waiting to run
Build RPCSX / build-linux (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.1-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.2-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.4-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.5-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9.1-a) (push) Waiting to run
Build RPCSX / build-android (x86_64, x86-64) (push) Waiting to run

This commit is contained in:
DH 2025-12-04 21:37:16 +03:00
parent 06f86132c3
commit a70fecb111

View file

@ -2,6 +2,7 @@
#include "SpvConverter.hpp" #include "SpvConverter.hpp"
#include "analyze.hpp" #include "analyze.hpp"
#include "dialect.hpp" #include "dialect.hpp"
#include <algorithm>
#include <list> #include <list>
#include <rx/die.hpp> #include <rx/die.hpp>
@ -316,61 +317,61 @@ toCanonicalSwitchSelectionConstruct(spv::Context &context,
return; return;
} }
std::vector<ir::Block> workList; {
std::vector<ir::Block> workList;
for (auto &[target, caseInfo] : cases) { for (auto &[target, caseInfo] : cases) {
workList.push_back(target); workList.push_back(target);
while (!workList.empty()) { while (!workList.empty()) {
auto block = workList.back(); auto block = workList.back();
workList.pop_back(); workList.pop_back();
if (block == mergeBlock) { if (block == mergeBlock) {
continue; continue;
} }
if (block != target && cases.contains(block)) { if (block != target && cases.contains(block)) {
caseInfo.fallthroughBlock = block; caseInfo.fallthroughBlock = block;
workList.clear(); workList.clear();
break; break;
} }
if (auto construct = block.cast<ir::Construct>()) { if (auto construct = block.cast<ir::Construct>()) {
workList.push_back(construct.getMerge()); workList.push_back(construct.getMerge());
continue; continue;
} }
for (auto succ : getSuccessors(block)) { for (auto succ : getSuccessors(block)) {
workList.push_back(succ); workList.push_back(succ);
}
} }
} }
} }
std::list<ir::Block> sortedCases; std::list<ir::Block> sortedCases;
std::list<std::pair<ir::Block, ir::Block>> workList;
for (auto &[target, caseInfo] : cases) { for (auto &[target, caseInfo] : cases) {
if (caseInfo.fallthroughBlock == nullptr) { if (caseInfo.fallthroughBlock == nullptr) {
sortedCases.push_back(target); sortedCases.push_back(target);
} else {
workList.emplace_back(target, caseInfo.fallthroughBlock);
} }
} }
assert(!sortedCases.empty()); assert(!sortedCases.empty());
for (auto &[target, caseInfo] : cases) { while (!workList.empty()) {
if (caseInfo.fallthroughBlock == nullptr) { auto [block, fallthroughBlock] = workList.front();
continue; workList.pop_front();
if (auto it = std::ranges::find(sortedCases, fallthroughBlock);
it != sortedCases.end()) {
sortedCases.insert(it, block);
} else {
workList.emplace_back(block, fallthroughBlock);
} }
auto it = sortedCases.begin();
while (it != sortedCases.end()) {
if (caseInfo.fallthroughBlock == *it) {
break;
}
++it;
}
sortedCases.insert(it, target);
} }
for (auto target : sortedCases) { for (auto target : sortedCases) {