summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-24 20:59:49 -0300
committerGravatar ameerj2021-07-22 21:51:33 -0400
commit9fbfe7d676790dea160368eda6492e8feb6e2f4a (patch)
tree81bc6a375849fc6b114ec5cf26880bd93656099c /src/shader_recompiler/backend/glasm
parentgl_shader_cache: Do not flip tessellation on OpenGL (diff)
downloadyuzu-9fbfe7d676790dea160368eda6492e8feb6e2f4a.tar.gz
yuzu-9fbfe7d676790dea160368eda6492e8feb6e2f4a.tar.xz
yuzu-9fbfe7d676790dea160368eda6492e8feb6e2f4a.zip
glasm: Fix usage counting on phi nodes
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp12
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h2
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp16
3 files changed, 22 insertions, 8 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 8718cc7ec..2ce839059 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -178,6 +178,10 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) {
178 throw LogicError("Invalid opcode {}", inst->GetOpcode()); 178 throw LogicError("Invalid opcode {}", inst->GetOpcode());
179} 179}
180 180
181bool IsReference(IR::Inst& inst) {
182 return inst.GetOpcode() == IR::Opcode::Reference;
183}
184
181void Precolor(EmitContext& ctx, const IR::Program& program) { 185void Precolor(EmitContext& ctx, const IR::Program& program) {
182 for (IR::Block* const block : program.blocks) { 186 for (IR::Block* const block : program.blocks) {
183 for (IR::Inst& phi : block->Instructions() | std::views::take_while(IR::IsPhi)) { 187 for (IR::Inst& phi : block->Instructions() | std::views::take_while(IR::IsPhi)) {
@@ -194,11 +198,13 @@ void Precolor(EmitContext& ctx, const IR::Program& program) {
194 default: 198 default:
195 throw NotImplementedException("Phi node type {}", phi.Type()); 199 throw NotImplementedException("Phi node type {}", phi.Type());
196 } 200 }
201 // Insert phi moves before references to avoid overwritting them
197 const size_t num_args{phi.NumArgs()}; 202 const size_t num_args{phi.NumArgs()};
198 for (size_t i = 0; i < num_args; ++i) { 203 for (size_t i = 0; i < num_args; ++i) {
199 IR::IREmitter{*phi.PhiBlock(i)}.PhiMove(phi, phi.Arg(i)); 204 IR::Block& phi_block{*phi.PhiBlock(i)};
205 auto it{std::find_if_not(phi_block.rbegin(), phi_block.rend(), IsReference).base()};
206 IR::IREmitter{phi_block, it}.PhiMove(phi, phi.Arg(i));
200 } 207 }
201 // Add reference to the phi node on the phi predecessor to avoid overwritting it
202 for (size_t i = 0; i < num_args; ++i) { 208 for (size_t i = 0; i < num_args; ++i) {
203 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi}); 209 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi});
204 } 210 }
@@ -237,7 +243,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
237 } 243 }
238 } else { 244 } else {
239 ctx.Add("MOV.S.CC RC,{};" 245 ctx.Add("MOV.S.CC RC,{};"
240 "BRK (EQ.x);" 246 "BRK(EQ.x);"
241 "ENDREP;", 247 "ENDREP;",
242 eval(node.data.repeat.cond)); 248 eval(node.data.repeat.cond));
243 } 249 }
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 5e038b332..cc7aa8e20 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -23,7 +23,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst);
23void EmitVoid(EmitContext& ctx); 23void EmitVoid(EmitContext& ctx);
24void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); 24void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
25void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); 25void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
26void EmitReference(EmitContext&); 26void EmitReference(EmitContext&, const IR::Value& value);
27void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); 27void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value);
28void EmitJoin(EmitContext& ctx); 28void EmitJoin(EmitContext& ctx);
29void EmitDemoteToHelperInvocation(EmitContext& ctx); 29void EmitDemoteToHelperInvocation(EmitContext& ctx);
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
index 756134d02..3d7a3ebb4 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
@@ -17,18 +17,26 @@ namespace Shader::Backend::GLASM {
17 17
18#define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__) 18#define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__)
19 19
20void EmitPhi(EmitContext&, IR::Inst&) {} 20void EmitPhi(EmitContext& ctx, IR::Inst& inst) {
21 const size_t num_args{inst.NumArgs()};
22 for (size_t i = 0; i < num_args; ++i) {
23 ctx.reg_alloc.Consume(inst.Arg(i));
24 }
25}
21 26
22void EmitVoid(EmitContext&) {} 27void EmitVoid(EmitContext&) {}
23 28
24void EmitReference(EmitContext&) {} 29void EmitReference(EmitContext& ctx, const IR::Value& value) {
30 ctx.reg_alloc.Consume(value);
31}
25 32
26void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { 33void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) {
34 const Register phi_reg{ctx.reg_alloc.Consume(phi)};
35 const Value eval_value{ctx.reg_alloc.Consume(value)};
36
27 if (phi == value) { 37 if (phi == value) {
28 return; 38 return;
29 } 39 }
30 const Register phi_reg{ctx.reg_alloc.Consume(phi)};
31 const Value eval_value{ctx.reg_alloc.Consume(value)};
32 switch (phi.Inst()->Flags<IR::Type>()) { 40 switch (phi.Inst()->Flags<IR::Type>()) {
33 case IR::Type::U1: 41 case IR::Type::U1:
34 case IR::Type::U32: 42 case IR::Type::U32: