diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 24 |
3 files changed, 30 insertions, 2 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index 9b866f889..67f9dad68 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | |||
| @@ -68,7 +68,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | |||
| 68 | } | 68 | } |
| 69 | if (!phi.Definition<Id>().is_valid) { | 69 | if (!phi.Definition<Id>().is_valid) { |
| 70 | // The phi node wasn't forward defined | 70 | // The phi node wasn't forward defined |
| 71 | ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type()); | 71 | ctx.var_alloc.PhiDefine(phi, phi.Type()); |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | 74 | ||
| @@ -80,7 +80,7 @@ void EmitReference(EmitContext& ctx, const IR::Value& value) { | |||
| 80 | 80 | ||
| 81 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | 81 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { |
| 82 | IR::Inst& phi{*phi_value.InstRecursive()}; | 82 | IR::Inst& phi{*phi_value.InstRecursive()}; |
| 83 | const auto phi_type{phi.Arg(0).Type()}; | 83 | const auto phi_type{phi.Type()}; |
| 84 | if (!phi.Definition<Id>().is_valid) { | 84 | if (!phi.Definition<Id>().is_valid) { |
| 85 | // The phi node wasn't forward defined | 85 | // The phi node wasn't forward defined |
| 86 | ctx.var_alloc.PhiDefine(phi, phi_type); | 86 | ctx.var_alloc.PhiDefine(phi, phi_type); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index e563b4022..30b470bdd 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -254,6 +254,10 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | IR::Type Inst::Type() const { | 256 | IR::Type Inst::Type() const { |
| 257 | if (op == IR::Opcode::Phi) { | ||
| 258 | // The type of a phi node is stored in its flags | ||
| 259 | return Flags<IR::Type>(); | ||
| 260 | } | ||
| 257 | return TypeOf(op); | 261 | return TypeOf(op); |
| 258 | } | 262 | } |
| 259 | 263 | ||
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 | } |