diff options
12 files changed, 36 insertions, 16 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index d7a08e4b3..a893fa3fb 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -200,7 +200,7 @@ void Precolor(EmitContext& ctx, const IR::Program& program) { | |||
| 200 | } | 200 | } |
| 201 | // Add reference to the phi node on the phi predecessor to avoid overwritting it | 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) { | 202 | for (size_t i = 0; i < num_args; ++i) { |
| 203 | IR::IREmitter{*phi.PhiBlock(i)}.DummyReference(IR::Value{&phi}); | 203 | IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi}); |
| 204 | } | 204 | } |
| 205 | } | 205 | } |
| 206 | } | 206 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp index cdbf6e93e..505378bfd 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp | |||
| @@ -22,6 +22,10 @@ void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { | |||
| 22 | Alias(inst, value); | 22 | Alias(inst, value); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void EmitConditionRef(EmitContext&, IR::Inst& inst, const IR::Value& value) { | ||
| 26 | Alias(inst, value); | ||
| 27 | } | ||
| 28 | |||
| 25 | void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) { | 29 | void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) { |
| 26 | Alias(inst, value); | 30 | Alias(inst, value); |
| 27 | } | 31 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index 54e7fab3c..df0933a3f 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h | |||
| @@ -22,7 +22,8 @@ class EmitContext; | |||
| 22 | void EmitPhi(EmitContext& ctx, IR::Inst& inst); | 22 | void EmitPhi(EmitContext& ctx, IR::Inst& inst); |
| 23 | void EmitVoid(EmitContext& ctx); | 23 | void EmitVoid(EmitContext& ctx); |
| 24 | void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | 24 | void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); |
| 25 | void EmitDummyReference(EmitContext&); | 25 | void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); |
| 26 | void EmitReference(EmitContext&); | ||
| 26 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | 27 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); |
| 27 | void EmitJoin(EmitContext& ctx); | 28 | void EmitJoin(EmitContext& ctx); |
| 28 | void EmitDemoteToHelperInvocation(EmitContext& ctx); | 29 | void 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 a4c1ca481..015cb5576 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -21,7 +21,7 @@ void EmitPhi(EmitContext&, IR::Inst&) {} | |||
| 21 | 21 | ||
| 22 | void EmitVoid(EmitContext&) {} | 22 | void EmitVoid(EmitContext&) {} |
| 23 | 23 | ||
| 24 | void EmitDummyReference(EmitContext&) {} | 24 | void EmitReference(EmitContext&) {} |
| 25 | 25 | ||
| 26 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { | 26 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { |
| 27 | if (phi == value) { | 27 | if (phi == value) { |
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 707b22247..1a88331b4 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -139,6 +139,7 @@ void RegAlloc::Free(Id id) { | |||
| 139 | /*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) { | 139 | /*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) { |
| 140 | switch (inst.GetOpcode()) { | 140 | switch (inst.GetOpcode()) { |
| 141 | case IR::Opcode::Identity: | 141 | case IR::Opcode::Identity: |
| 142 | case IR::Opcode::ConditionRef: | ||
| 142 | case IR::Opcode::BitCastU16F16: | 143 | case IR::Opcode::BitCastU16F16: |
| 143 | case IR::Opcode::BitCastU32F32: | 144 | case IR::Opcode::BitCastU32F32: |
| 144 | case IR::Opcode::BitCastU64F64: | 145 | case IR::Opcode::BitCastU64F64: |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 9ed2af991..3e20ac3b9 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -469,7 +469,15 @@ Id EmitIdentity(EmitContext& ctx, const IR::Value& value) { | |||
| 469 | return id; | 469 | return id; |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | void EmitDummyReference(EmitContext&) {} | 472 | Id EmitConditionRef(EmitContext& ctx, const IR::Value& value) { |
| 473 | const Id id{ctx.Def(value)}; | ||
| 474 | if (!Sirit::ValidId(id)) { | ||
| 475 | throw NotImplementedException("Forward identity declaration"); | ||
| 476 | } | ||
| 477 | return id; | ||
| 478 | } | ||
| 479 | |||
| 480 | void EmitReference(EmitContext&) {} | ||
| 473 | 481 | ||
| 474 | void EmitPhiMove(EmitContext&) { | 482 | void EmitPhiMove(EmitContext&) { |
| 475 | throw LogicError("Unreachable instruction"); | 483 | throw LogicError("Unreachable instruction"); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 22260d2a9..1181e7b4f 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h | |||
| @@ -23,7 +23,8 @@ class EmitContext; | |||
| 23 | Id EmitPhi(EmitContext& ctx, IR::Inst* inst); | 23 | Id EmitPhi(EmitContext& ctx, IR::Inst* inst); |
| 24 | void EmitVoid(EmitContext& ctx); | 24 | void EmitVoid(EmitContext& ctx); |
| 25 | Id EmitIdentity(EmitContext& ctx, const IR::Value& value); | 25 | Id EmitIdentity(EmitContext& ctx, const IR::Value& value); |
| 26 | void EmitDummyReference(EmitContext&); | 26 | Id EmitConditionRef(EmitContext& ctx, const IR::Value& value); |
| 27 | void EmitReference(EmitContext&); | ||
| 27 | void EmitPhiMove(EmitContext&); | 28 | void EmitPhiMove(EmitContext&); |
| 28 | void EmitJoin(EmitContext& ctx); | 29 | void EmitJoin(EmitContext& ctx); |
| 29 | void EmitDemoteToHelperInvocation(EmitContext& ctx); | 30 | void EmitDemoteToHelperInvocation(EmitContext& ctx); |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 94bdbe39c..e9fd41237 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -61,8 +61,12 @@ F64 IREmitter::Imm64(f64 value) const { | |||
| 61 | return F64{Value{value}}; | 61 | return F64{Value{value}}; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | void IREmitter::DummyReference(const Value& value) { | 64 | U1 IREmitter::ConditionRef(const U1& value) { |
| 65 | Inst(Opcode::DummyReference, value); | 65 | return Inst<U1>(Opcode::ConditionRef, value); |
| 66 | } | ||
| 67 | |||
| 68 | void IREmitter::Reference(const Value& value) { | ||
| 69 | Inst(Opcode::Reference, value); | ||
| 66 | } | 70 | } |
| 67 | 71 | ||
| 68 | void IREmitter::PhiMove(IR::Inst& phi, const Value& value) { | 72 | void IREmitter::PhiMove(IR::Inst& phi, const Value& value) { |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 4ae69b788..bb3500c54 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -32,7 +32,9 @@ public: | |||
| 32 | [[nodiscard]] U64 Imm64(s64 value) const; | 32 | [[nodiscard]] U64 Imm64(s64 value) const; |
| 33 | [[nodiscard]] F64 Imm64(f64 value) const; | 33 | [[nodiscard]] F64 Imm64(f64 value) const; |
| 34 | 34 | ||
| 35 | void DummyReference(const Value& value); | 35 | U1 ConditionRef(const U1& value); |
| 36 | void Reference(const Value& value); | ||
| 37 | |||
| 36 | void PhiMove(IR::Inst& phi, const Value& value); | 38 | void PhiMove(IR::Inst& phi, const Value& value); |
| 37 | 39 | ||
| 38 | void Prologue(); | 40 | void Prologue(); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 267aebc61..3dfa5a880 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -56,7 +56,8 @@ Inst::~Inst() { | |||
| 56 | 56 | ||
| 57 | bool Inst::MayHaveSideEffects() const noexcept { | 57 | bool Inst::MayHaveSideEffects() const noexcept { |
| 58 | switch (op) { | 58 | switch (op) { |
| 59 | case Opcode::DummyReference: | 59 | case Opcode::ConditionRef: |
| 60 | case Opcode::Reference: | ||
| 60 | case Opcode::PhiMove: | 61 | case Opcode::PhiMove: |
| 61 | case Opcode::Prologue: | 62 | case Opcode::Prologue: |
| 62 | case Opcode::Epilogue: | 63 | case Opcode::Epilogue: |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 6196b867d..8a8d0d759 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -6,7 +6,8 @@ | |||
| 6 | OPCODE(Phi, Opaque, ) | 6 | OPCODE(Phi, Opaque, ) |
| 7 | OPCODE(Identity, Opaque, Opaque, ) | 7 | OPCODE(Identity, Opaque, Opaque, ) |
| 8 | OPCODE(Void, Void, ) | 8 | OPCODE(Void, Void, ) |
| 9 | OPCODE(DummyReference, Void, Opaque, ) | 9 | OPCODE(ConditionRef, U1, U1, ) |
| 10 | OPCODE(Reference, Void, Opaque, ) | ||
| 10 | OPCODE(PhiMove, Void, Opaque, Opaque, ) | 11 | OPCODE(PhiMove, Void, Opaque, Opaque, ) |
| 11 | 12 | ||
| 12 | // Special operations | 13 | // Special operations |
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 83554a953..ebe5c2654 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -703,8 +703,7 @@ private: | |||
| 703 | 703 | ||
| 704 | // Implement if header block | 704 | // Implement if header block |
| 705 | IR::IREmitter ir{*current_block}; | 705 | IR::IREmitter ir{*current_block}; |
| 706 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | 706 | const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; |
| 707 | ir.DummyReference(cond); | ||
| 708 | 707 | ||
| 709 | const size_t if_node_index{syntax_list.size()}; | 708 | const size_t if_node_index{syntax_list.size()}; |
| 710 | syntax_list.emplace_back(); | 709 | syntax_list.emplace_back(); |
| @@ -754,8 +753,7 @@ private: | |||
| 754 | 753 | ||
| 755 | // The continue block is located at the end of the loop | 754 | // The continue block is located at the end of the loop |
| 756 | IR::IREmitter ir{*continue_block}; | 755 | IR::IREmitter ir{*continue_block}; |
| 757 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | 756 | const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; |
| 758 | ir.DummyReference(cond); | ||
| 759 | 757 | ||
| 760 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; | 758 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; |
| 761 | loop_header_block->AddBranch(body_block); | 759 | loop_header_block->AddBranch(body_block); |
| @@ -791,8 +789,7 @@ private: | |||
| 791 | IR::Block* const skip_block{MergeBlock(parent, stmt)}; | 789 | IR::Block* const skip_block{MergeBlock(parent, stmt)}; |
| 792 | 790 | ||
| 793 | IR::IREmitter ir{*current_block}; | 791 | IR::IREmitter ir{*current_block}; |
| 794 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | 792 | const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; |
| 795 | ir.DummyReference(cond); | ||
| 796 | current_block->AddBranch(break_block); | 793 | current_block->AddBranch(break_block); |
| 797 | current_block->AddBranch(skip_block); | 794 | current_block->AddBranch(skip_block); |
| 798 | current_block = skip_block; | 795 | current_block = skip_block; |