diff options
| author | 2021-04-22 18:33:49 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:29 -0400 | |
| commit | 25949b864c40405946d434ecc85d6c167f323a24 (patch) | |
| tree | 3e7025cd196437b2090188b2ac9bbb765a891719 /src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |
| parent | shader: Remove invalidated blocks in dead code elimination pass (diff) | |
| download | yuzu-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.cpp | 24 |
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; |