diff options
Diffstat (limited to 'src')
3 files changed, 42 insertions, 13 deletions
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 a6c66b826..cdbf6e93e 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp | |||
| @@ -12,12 +12,10 @@ static void Alias(IR::Inst& inst, const IR::Value& value) { | |||
| 12 | if (value.IsImmediate()) { | 12 | if (value.IsImmediate()) { |
| 13 | return; | 13 | return; |
| 14 | } | 14 | } |
| 15 | IR::Inst* const value_inst{value.InstRecursive()}; | 15 | IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())}; |
| 16 | if (inst.GetOpcode() == IR::Opcode::Identity) { | 16 | value_inst.DestructiveAddUsage(inst.UseCount()); |
| 17 | value_inst->DestructiveAddUsage(inst.UseCount()); | 17 | value_inst.DestructiveRemoveUsage(); |
| 18 | value_inst->DestructiveRemoveUsage(); | 18 | inst.SetDefinition(value_inst.Definition<Id>()); |
| 19 | } | ||
| 20 | inst.SetDefinition(value_inst->Definition<Id>()); | ||
| 21 | } | 19 | } |
| 22 | 20 | ||
| 23 | void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { | 21 | void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { |
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 0e38f467f..707b22247 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -30,9 +30,10 @@ Value RegAlloc::Consume(const IR::Value& value) { | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | void RegAlloc::Unref(IR::Inst& inst) { | 32 | void RegAlloc::Unref(IR::Inst& inst) { |
| 33 | inst.DestructiveRemoveUsage(); | 33 | IR::Inst& value_inst{AliasInst(inst)}; |
| 34 | if (!inst.HasUses()) { | 34 | value_inst.DestructiveRemoveUsage(); |
| 35 | Free(inst.Definition<Id>()); | 35 | if (!value_inst.HasUses()) { |
| 36 | Free(value_inst.Definition<Id>()); | ||
| 36 | } | 37 | } |
| 37 | } | 38 | } |
| 38 | 39 | ||
| @@ -99,10 +100,7 @@ Value RegAlloc::PeekInst(IR::Inst& inst) { | |||
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | Value RegAlloc::ConsumeInst(IR::Inst& inst) { | 102 | Value RegAlloc::ConsumeInst(IR::Inst& inst) { |
| 102 | inst.DestructiveRemoveUsage(); | 103 | Unref(inst); |
| 103 | if (!inst.HasUses()) { | ||
| 104 | Free(inst.Definition<Id>()); | ||
| 105 | } | ||
| 106 | return PeekInst(inst); | 104 | return PeekInst(inst); |
| 107 | } | 105 | } |
| 108 | 106 | ||
| @@ -138,4 +136,31 @@ void RegAlloc::Free(Id id) { | |||
| 138 | } | 136 | } |
| 139 | } | 137 | } |
| 140 | 138 | ||
| 139 | /*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) { | ||
| 140 | switch (inst.GetOpcode()) { | ||
| 141 | case IR::Opcode::Identity: | ||
| 142 | case IR::Opcode::BitCastU16F16: | ||
| 143 | case IR::Opcode::BitCastU32F32: | ||
| 144 | case IR::Opcode::BitCastU64F64: | ||
| 145 | case IR::Opcode::BitCastF16U16: | ||
| 146 | case IR::Opcode::BitCastF32U32: | ||
| 147 | case IR::Opcode::BitCastF64U64: | ||
| 148 | return true; | ||
| 149 | default: | ||
| 150 | return false; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | /*static*/ IR::Inst& RegAlloc::AliasInst(IR::Inst& inst) { | ||
| 155 | IR::Inst* it{&inst}; | ||
| 156 | while (IsAliased(*it)) { | ||
| 157 | const IR::Value arg{it->Arg(0)}; | ||
| 158 | if (arg.IsImmediate()) { | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | it = arg.InstRecursive(); | ||
| 162 | } | ||
| 163 | return *it; | ||
| 164 | } | ||
| 165 | |||
| 141 | } // namespace Shader::Backend::GLASM | 166 | } // namespace Shader::Backend::GLASM |
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h index ede6edd1f..41b7c92be 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.h +++ b/src/shader_recompiler/backend/glasm/reg_alloc.h | |||
| @@ -126,6 +126,12 @@ public: | |||
| 126 | return num_used_long_registers; | 126 | return num_used_long_registers; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | /// Returns true if the instruction is expected to be aliased to another | ||
| 130 | static bool IsAliased(const IR::Inst& inst); | ||
| 131 | |||
| 132 | /// Returns the underlying value out of an alias sequence | ||
| 133 | static IR::Inst& AliasInst(IR::Inst& inst); | ||
| 134 | |||
| 129 | private: | 135 | private: |
| 130 | static constexpr size_t NUM_REGS = 4096; | 136 | static constexpr size_t NUM_REGS = 4096; |
| 131 | static constexpr size_t NUM_ELEMENTS = 4; | 137 | static constexpr size_t NUM_ELEMENTS = 4; |