summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-22 18:33:49 -0300
committerGravatar ameerj2021-07-22 21:51:29 -0400
commit25949b864c40405946d434ecc85d6c167f323a24 (patch)
tree3e7025cd196437b2090188b2ac9bbb765a891719 /src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
parentshader: Remove invalidated blocks in dead code elimination pass (diff)
downloadyuzu-25949b864c40405946d434ecc85d6c167f323a24.tar.gz
yuzu-25949b864c40405946d434ecc85d6c167f323a24.tar.xz
yuzu-25949b864c40405946d434ecc85d6c167f323a24.zip
shader: Fix forward referencing identity instructions when inserting phi
Diffstat (limited to 'src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index 3bab742e7..a8064a5d0 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -278,20 +278,22 @@ private:
278 } 278 }
279 same = op; 279 same = op;
280 } 280 }
281 // Remove the phi node from the block, it will be reinserted
282 IR::Block::InstructionList& list{block->Instructions()};
283 list.erase(IR::Block::InstructionList::s_iterator_to(phi));
284
285 // Find the first non-phi instruction and use it as an insertion point
286 IR::Block::iterator reinsert_point{std::ranges::find_if_not(list, IsPhi)};
281 if (same.IsEmpty()) { 287 if (same.IsEmpty()) {
282 // The phi is unreachable or in the start block 288 // The phi is unreachable or in the start block
283 // First remove the phi node from the block, it will be reinserted 289 // Insert an undefined instruction and make it the phi node replacement
284 IR::Block::InstructionList& list{block->Instructions()}; 290 // The "phi" node reinsertion point is specified after this instruction
285 list.erase(IR::Block::InstructionList::s_iterator_to(phi)); 291 reinsert_point = block->PrependNewInst(reinsert_point, undef_opcode);
286 292 same = IR::Value{&*reinsert_point};
287 // Insert an undef instruction after all phi nodes (to keep phi instructions on top) 293 ++reinsert_point;
288 const auto first_not_phi{std::ranges::find_if_not(list, IsPhi)};
289 same = IR::Value{&*block->PrependNewInst(first_not_phi, undef_opcode)};
290
291 // Insert the phi node after the undef opcode, this will be replaced with an identity
292 list.insert(first_not_phi, phi);
293 } 294 }
294 // Reroute all uses of phi to same and remove phi 295 // Reinsert the phi node and reroute all its uses to the "same" value
296 list.insert(reinsert_point, phi);
295 phi.ReplaceUsesWith(same); 297 phi.ReplaceUsesWith(same);
296 // TODO: Try to recursively remove all phi users, which might have become trivial 298 // TODO: Try to recursively remove all phi users, which might have become trivial
297 return same; 299 return same;