diff options
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, 24 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 5545f8197..87aa09358 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | // https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6 | 14 | // https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6 |
| 15 | // | 15 | // |
| 16 | 16 | ||
| 17 | #include <deque> | ||
| 17 | #include <span> | 18 | #include <span> |
| 18 | #include <variant> | 19 | #include <variant> |
| 19 | #include <vector> | 20 | #include <vector> |
| @@ -370,6 +371,26 @@ void VisitBlock(Pass& pass, IR::Block* block) { | |||
| 370 | } | 371 | } |
| 371 | pass.SealBlock(block); | 372 | pass.SealBlock(block); |
| 372 | } | 373 | } |
| 374 | |||
| 375 | IR::Type GetConcreteType(IR::Inst* inst) { | ||
| 376 | std::deque<IR::Inst*> queue; | ||
| 377 | queue.push_back(inst); | ||
| 378 | while (!queue.empty()) { | ||
| 379 | IR::Inst* current = queue.front(); | ||
| 380 | queue.pop_front(); | ||
| 381 | const size_t num_args{current->NumArgs()}; | ||
| 382 | for (size_t i = 0; i < num_args; ++i) { | ||
| 383 | const auto set_type = current->Arg(i).Type(); | ||
| 384 | if (set_type != IR::Type::Opaque) { | ||
| 385 | return set_type; | ||
| 386 | } | ||
| 387 | if (!current->Arg(i).IsImmediate()) { | ||
| 388 | queue.push_back(current->Arg(i).Inst()); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | } | ||
| 392 | return IR::Type::Opaque; | ||
| 393 | } | ||
| 373 | } // Anonymous namespace | 394 | } // Anonymous namespace |
| 374 | 395 | ||
| 375 | void SsaRewritePass(IR::Program& program) { | 396 | void SsaRewritePass(IR::Program& program) { |
| @@ -381,6 +402,9 @@ void SsaRewritePass(IR::Program& program) { | |||
| 381 | for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { | 402 | for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { |
| 382 | for (IR::Inst& inst : (*block)->Instructions()) { | 403 | for (IR::Inst& inst : (*block)->Instructions()) { |
| 383 | if (inst.GetOpcode() == IR::Opcode::Phi) { | 404 | if (inst.GetOpcode() == IR::Opcode::Phi) { |
| 405 | if (inst.Type() == IR::Type::Opaque) { | ||
| 406 | inst.SetFlags(GetConcreteType(&inst)); | ||
| 407 | } | ||
| 384 | inst.OrderPhiArgs(); | 408 | inst.OrderPhiArgs(); |
| 385 | } | 409 | } |
| 386 | } | 410 | } |