diff --git a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp index 29151f0c9..8729678f3 100644 --- a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp +++ b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp @@ -668,7 +668,6 @@ void PruneUnreachableBlocks(Graph& graph) { RemapIds(block.successors, id_map); block.predecessors.clear(); block.dominators.clear(); - block.post_dominators.clear(); auto& terminator = block.terminator; terminator.true_block = RemapId(terminator.true_block, id_map); terminator.false_block = RemapId(terminator.false_block, id_map); @@ -721,37 +720,6 @@ void ComputeDominators(Graph& graph) { } } -void ComputePostDominators(Graph& graph) { - const auto count = static_cast(graph.blocks.size()); - const auto all = AllBlockIds(count); - - for (auto& block: graph.blocks) { - block.post_dominators = block.successors.empty() ? std::vector {block.id} : all; - } - - bool changed = true; - while (changed) { - changed = false; - for (auto& block: graph.blocks) { - std::vector next; - if (block.successors.empty()) { - next = {block.id}; - } else { - next = graph.blocks[block.successors.front()].post_dominators; - for (uint32_t i = 1; i < block.successors.size(); i++) { - next = IntersectSorted(next, graph.blocks[block.successors[i]].post_dominators); - } - AddUnique(next, block.id); - SortUnique(next); - } - if (next != block.post_dominators) { - block.post_dominators = std::move(next); - changed = true; - } - } - } -} - void ComputeBackEdges(Graph& graph) { graph.back_edges.clear(); for (const auto& block: graph.blocks) { @@ -809,31 +777,9 @@ void ComputeNaturalLoops(Graph& graph) { edge.natural = natural; NaturalLoop loop; - loop.header = edge.to; - loop.latch = edge.from; - loop.continue_block = edge.from; - loop.body_blocks = std::move(body); - - for (auto block_id: loop.body_blocks) { - const auto* block = graph.FindBlock(block_id); - if (block == nullptr) { - continue; - } - for (auto succ: block->successors) { - if (!Contains(loop.body_blocks, succ)) { - AddUnique(loop.exit_blocks, succ); - } - } - } - SortUnique(loop.exit_blocks); - - if (!loop.exit_blocks.empty()) { - uint32_t merge = loop.exit_blocks.front(); - for (uint32_t i = 1; i < loop.exit_blocks.size(); i++) { - merge = graph.FindNearestCommonPostDominator(merge, loop.exit_blocks[i]); - } - loop.merge = merge; - } + loop.header = edge.to; + loop.latch = edge.from; + loop.body_blocks = std::move(body); graph.natural_loops.push_back(std::move(loop)); } } @@ -933,7 +879,6 @@ void ComputeComponents(Graph& graph) { void RecomputeAnalyses(Graph& graph) { ComputeDominators(graph); - ComputePostDominators(graph); ComputeBackEdges(graph); ComputeNaturalLoops(graph); ComputeComponents(graph); @@ -952,7 +897,6 @@ std::vector ApplyBlockOrder(Graph& graph, std::vector bloc RemapIds(block.predecessors, id_map); RemapIds(block.successors, id_map); RemapIds(block.dominators, id_map); - RemapIds(block.post_dominators, id_map); block.terminator.true_block = RemapId(block.terminator.true_block, id_map); block.terminator.false_block = RemapId(block.terminator.false_block, id_map); block.terminator.merge_block = RemapId(block.terminator.merge_block, id_map); @@ -1009,34 +953,6 @@ bool Graph::Dominates(uint32_t dominator, uint32_t block) const { return target != nullptr && Contains(target->dominators, dominator); } -bool Graph::PostDominates(uint32_t post_dominator, uint32_t block) const { - const auto* target = FindBlock(block); - return target != nullptr && Contains(target->post_dominators, post_dominator); -} - -uint32_t Graph::FindNearestCommonPostDominator(uint32_t block_a, uint32_t block_b) const { - const auto* a = FindBlock(block_a); - const auto* b = FindBlock(block_b); - if (a == nullptr || b == nullptr) { - return UINT32_MAX; - } - - const auto common = IntersectSorted(a->post_dominators, b->post_dominators); - for (auto candidate: common) { - bool nearest = true; - for (auto other: common) { - if (other != candidate && !PostDominates(other, candidate)) { - nearest = false; - break; - } - } - if (nearest) { - return candidate; - } - } - return common.empty() ? UINT32_MAX : common.front(); -} - namespace { // Eliminate gotos by moving them through a structured statement tree. Every Code node @@ -1814,9 +1730,7 @@ std::string GraphToString(const Graph& graph) { text += fmt::format(" predecessors=[{}] successors=[{}]\n", VectorToString(block.predecessors).c_str(), VectorToString(block.successors).c_str()); - text += fmt::format(" dominators=[{}] post_dominators=[{}]\n", - VectorToString(block.dominators).c_str(), - VectorToString(block.post_dominators).c_str()); + text += fmt::format(" dominators=[{}]\n", VectorToString(block.dominators).c_str()); text += fmt::format( " terminator={} condition={} true={} false={} merge={} continue={} loop_header={} " "indirect_sgpr={} indirect_selector={} indirect_targets=[{}] selector_values=[{}] " @@ -1843,10 +1757,8 @@ std::string GraphToString(const Graph& graph) { edge.natural ? 1u : 0u); } for (const auto& loop: graph.natural_loops) { - text += fmt::format("loop header={} latch={} merge={} continue={} body=[{}] exits=[{}]\n", - loop.header, loop.latch, loop.merge, loop.continue_block, - VectorToString(loop.body_blocks).c_str(), - VectorToString(loop.exit_blocks).c_str()); + text += fmt::format("loop header={} latch={} body=[{}]\n", loop.header, loop.latch, + VectorToString(loop.body_blocks).c_str()); } for (const auto& component: graph.components) { text += fmt::format("scc blocks=[{}] entries=[{}] irreducible={}\n", diff --git a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.h b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.h index 035f557d6..a051bf2f5 100644 --- a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.h +++ b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.h @@ -70,7 +70,6 @@ struct BasicBlock { std::vector predecessors; std::vector successors; std::vector dominators; - std::vector post_dominators; Terminator terminator; }; @@ -81,12 +80,9 @@ struct BackEdge { }; struct NaturalLoop { - uint32_t header = UINT32_MAX; - uint32_t latch = UINT32_MAX; - uint32_t merge = UINT32_MAX; - uint32_t continue_block = UINT32_MAX; + uint32_t header = UINT32_MAX; + uint32_t latch = UINT32_MAX; std::vector body_blocks; - std::vector exit_blocks; }; struct StronglyConnectedComponent { @@ -114,8 +110,6 @@ struct Graph { const BasicBlock* FindBlockByPc(uint32_t pc) const; BasicBlock* FindBlockByPc(uint32_t pc); bool Dominates(uint32_t dominator, uint32_t block) const; - bool PostDominates(uint32_t post_dominator, uint32_t block) const; - uint32_t FindNearestCommonPostDominator(uint32_t block_a, uint32_t block_b) const; }; Graph BuildGraph(const Decoder::Program& program); diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 782081916..258c7cd8d 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -8277,7 +8277,9 @@ void TestNewShaderRecompilerCfgMultipleLoopLatches() { Check(graph.back_edges.size() == 1u && graph.natural_loops.size() == 1u, "multiple native latches were not coalesced to one SPIR-V backedge"); const auto &loop = graph.natural_loops.front(); - const auto *continue_block = graph.FindBlock(loop.continue_block); + const auto *header = graph.FindBlock(loop.header); + Check(header != nullptr, "natural loop header is missing"); + const auto *continue_block = graph.FindBlock(header->terminator.continue_block); Check(continue_block != nullptr && continue_block->terminator.true_block == loop.header && graph.Dominates(loop.header, continue_block->id),