From 67159e3be76cf468288ae492ea22fc43a77a9d1e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 22 Mar 2022 18:34:31 -0400 Subject: dead_code_elimination_pass: Remove unreachable Phi arguments --- .../ir_opt/dead_code_elimination_pass.cpp | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp') diff --git a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp index 6c7c7b32d..6697fde85 100644 --- a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp +++ b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include + +#include + #include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/ir_opt/passes.h" @@ -25,7 +29,26 @@ void DeadInstElimination(IR::Block* const block) { } } +void DeletedPhiArgElimination(IR::Program& program, std::span dead_blocks) { + for (IR::Block* const block : program.blocks) { + for (IR::Inst& phi : *block) { + if (!IR::IsPhi(phi)) { + continue; + } + for (size_t i = 0; i < phi.NumArgs(); ++i) { + if (std::ranges::find(dead_blocks, phi.PhiBlock(i)) == dead_blocks.end()) { + continue; + } + // Phi operand at this index is an unreachable block + phi.ErasePhiOperand(i); + --i; + } + } + } +} + void DeadBranchElimination(IR::Program& program) { + boost::container::small_vector dead_blocks; const auto begin_it{program.syntax_list.begin()}; for (auto node_it = begin_it; node_it != program.syntax_list.end(); ++node_it) { if (node_it->type != IR::AbstractSyntaxNode::Type::If) { @@ -55,6 +78,7 @@ void DeadBranchElimination(IR::Program& program) { case IR::AbstractSyntaxNode::Type::Block: { IR::Block* const block{node_it->data.block}; DeadInstElimination(block); + dead_blocks.push_back(block); break; } default: @@ -66,6 +90,9 @@ void DeadBranchElimination(IR::Program& program) { // Account for loop increment --node_it; } + if (!dead_blocks.empty()) { + DeletedPhiArgElimination(program, std::span(dead_blocks.data(), dead_blocks.size())); + } } } // namespace -- cgit v1.2.3