summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_special.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp4
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp24
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
81void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { 81void 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
256IR::Type Inst::Type() const { 256IR::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
375IR::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
375void SsaRewritePass(IR::Program& program) { 396void 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 }