diff options
Diffstat (limited to 'src')
10 files changed, 104 insertions, 89 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 5022b5159..e29e448c7 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -25,6 +25,9 @@ EmitContext::EmitContext(IR::Program& program) { | |||
| 25 | f16.Define(*this, TypeFloat(16), "f16"); | 25 | f16.Define(*this, TypeFloat(16), "f16"); |
| 26 | f64.Define(*this, TypeFloat(64), "f64"); | 26 | f64.Define(*this, TypeFloat(64), "f64"); |
| 27 | 27 | ||
| 28 | true_value = ConstantTrue(u1); | ||
| 29 | false_value = ConstantFalse(u1); | ||
| 30 | |||
| 28 | for (const IR::Function& function : program.functions) { | 31 | for (const IR::Function& function : program.functions) { |
| 29 | for (IR::Block* const block : function.blocks) { | 32 | for (IR::Block* const block : function.blocks) { |
| 30 | block_label_map.emplace_back(block, OpLabel()); | 33 | block_label_map.emplace_back(block, OpLabel()); |
| @@ -58,6 +61,7 @@ EmitSPIRV::EmitSPIRV(IR::Program& program) { | |||
| 58 | std::fclose(file); | 61 | std::fclose(file); |
| 59 | std::system("spirv-dis shader.spv"); | 62 | std::system("spirv-dis shader.spv"); |
| 60 | std::system("spirv-val shader.spv"); | 63 | std::system("spirv-val shader.spv"); |
| 64 | std::system("spirv-cross shader.spv"); | ||
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | template <auto method> | 67 | template <auto method> |
| @@ -109,6 +113,8 @@ static Id TypeId(const EmitContext& ctx, IR::Type type) { | |||
| 109 | switch (type) { | 113 | switch (type) { |
| 110 | case IR::Type::U1: | 114 | case IR::Type::U1: |
| 111 | return ctx.u1; | 115 | return ctx.u1; |
| 116 | case IR::Type::U32: | ||
| 117 | return ctx.u32[1]; | ||
| 112 | default: | 118 | default: |
| 113 | throw NotImplementedException("Phi node type {}", type); | 119 | throw NotImplementedException("Phi node type {}", type); |
| 114 | } | 120 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 9aa83b5de..46ec7a1bb 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -79,6 +79,8 @@ public: | |||
| 79 | return def_map.Consume(value.Inst()); | 79 | return def_map.Consume(value.Inst()); |
| 80 | } | 80 | } |
| 81 | switch (value.Type()) { | 81 | switch (value.Type()) { |
| 82 | case IR::Type::U1: | ||
| 83 | return value.U1() ? true_value : false_value; | ||
| 82 | case IR::Type::U32: | 84 | case IR::Type::U32: |
| 83 | return Constant(u32[1], value.U32()); | 85 | return Constant(u32[1], value.U32()); |
| 84 | case IR::Type::F32: | 86 | case IR::Type::F32: |
| @@ -108,6 +110,9 @@ public: | |||
| 108 | VectorTypes f16; | 110 | VectorTypes f16; |
| 109 | VectorTypes f64; | 111 | VectorTypes f64; |
| 110 | 112 | ||
| 113 | Id true_value{}; | ||
| 114 | Id false_value{}; | ||
| 115 | |||
| 111 | Id workgroup_id{}; | 116 | Id workgroup_id{}; |
| 112 | Id local_invocation_id{}; | 117 | Id local_invocation_id{}; |
| 113 | 118 | ||
diff --git a/src/shader_recompiler/frontend/ir/basic_block.cpp b/src/shader_recompiler/frontend/ir/basic_block.cpp index b5616f394..c97626712 100644 --- a/src/shader_recompiler/frontend/ir/basic_block.cpp +++ b/src/shader_recompiler/frontend/ir/basic_block.cpp | |||
| @@ -113,7 +113,7 @@ static std::string ArgToIndex(const std::map<const Block*, size_t>& block_to_ind | |||
| 113 | if (arg.IsLabel()) { | 113 | if (arg.IsLabel()) { |
| 114 | return BlockToIndex(block_to_index, arg.Label()); | 114 | return BlockToIndex(block_to_index, arg.Label()); |
| 115 | } | 115 | } |
| 116 | if (!arg.IsImmediate()) { | 116 | if (!arg.IsImmediate() || arg.IsIdentity()) { |
| 117 | return fmt::format("%{}", InstIndex(inst_to_index, inst_index, arg.Inst())); | 117 | return fmt::format("%{}", InstIndex(inst_to_index, inst_index, arg.Inst())); |
| 118 | } | 118 | } |
| 119 | switch (arg.Type()) { | 119 | switch (arg.Type()) { |
| @@ -166,7 +166,7 @@ std::string DumpBlock(const Block& block, const std::map<const Block*, size_t>& | |||
| 166 | const std::string arg_str{ArgToIndex(block_to_index, inst_to_index, inst_index, arg)}; | 166 | const std::string arg_str{ArgToIndex(block_to_index, inst_to_index, inst_index, arg)}; |
| 167 | ret += arg_index != 0 ? ", " : " "; | 167 | ret += arg_index != 0 ? ", " : " "; |
| 168 | if (op == Opcode::Phi) { | 168 | if (op == Opcode::Phi) { |
| 169 | ret += fmt::format("[ {}, {} ]", arg_index, | 169 | ret += fmt::format("[ {}, {} ]", arg_str, |
| 170 | BlockToIndex(block_to_index, inst.PhiBlock(arg_index))); | 170 | BlockToIndex(block_to_index, inst.PhiBlock(arg_index))); |
| 171 | } else { | 171 | } else { |
| 172 | ret += arg_str; | 172 | ret += arg_str; |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 30932043f..f42489d41 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -46,10 +46,12 @@ F64 IREmitter::Imm64(f64 value) const { | |||
| 46 | 46 | ||
| 47 | void IREmitter::Branch(Block* label) { | 47 | void IREmitter::Branch(Block* label) { |
| 48 | label->AddImmediatePredecessor(block); | 48 | label->AddImmediatePredecessor(block); |
| 49 | block->SetBranch(label); | ||
| 49 | Inst(Opcode::Branch, label); | 50 | Inst(Opcode::Branch, label); |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 52 | void IREmitter::BranchConditional(const U1& condition, Block* true_label, Block* false_label) { | 53 | void IREmitter::BranchConditional(const U1& condition, Block* true_label, Block* false_label) { |
| 54 | block->SetBranches(IR::Condition{true}, true_label, false_label); | ||
| 53 | true_label->AddImmediatePredecessor(block); | 55 | true_label->AddImmediatePredecessor(block); |
| 54 | false_label->AddImmediatePredecessor(block); | 56 | false_label->AddImmediatePredecessor(block); |
| 55 | Inst(Opcode::BranchConditional, condition, true_label, false_label); | 57 | Inst(Opcode::BranchConditional, condition, true_label, false_label); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index b4ae371bd..9279b9692 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -143,19 +143,21 @@ Value Inst::Arg(size_t index) const { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void Inst::SetArg(size_t index, Value value) { | 145 | void Inst::SetArg(size_t index, Value value) { |
| 146 | if (op == Opcode::Phi) { | 146 | if (index >= NumArgs()) { |
| 147 | throw LogicError("Setting argument on a phi instruction"); | ||
| 148 | } | ||
| 149 | if (index >= NumArgsOf(op)) { | ||
| 150 | throw InvalidArgument("Out of bounds argument index {} in opcode {}", index, op); | 147 | throw InvalidArgument("Out of bounds argument index {} in opcode {}", index, op); |
| 151 | } | 148 | } |
| 152 | if (!args[index].IsImmediate()) { | 149 | const IR::Value arg{Arg(index)}; |
| 153 | UndoUse(args[index]); | 150 | if (!arg.IsImmediate()) { |
| 151 | UndoUse(arg); | ||
| 154 | } | 152 | } |
| 155 | if (!value.IsImmediate()) { | 153 | if (!value.IsImmediate()) { |
| 156 | Use(value); | 154 | Use(value); |
| 157 | } | 155 | } |
| 158 | args[index] = value; | 156 | if (op == Opcode::Phi) { |
| 157 | phi_args[index].second = value; | ||
| 158 | } else { | ||
| 159 | args[index] = value; | ||
| 160 | } | ||
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | Block* Inst::PhiBlock(size_t index) const { | 163 | Block* Inst::PhiBlock(size_t index) const { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp index 60f79b160..623e78ff8 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp | |||
| @@ -76,8 +76,8 @@ void IADD(TranslatorVisitor& v, u64 insn, IR::U32 op_b) { | |||
| 76 | } | 76 | } |
| 77 | } // Anonymous namespace | 77 | } // Anonymous namespace |
| 78 | 78 | ||
| 79 | void TranslatorVisitor::IADD_reg(u64) { | 79 | void TranslatorVisitor::IADD_reg(u64 insn) { |
| 80 | throw NotImplementedException("IADD (reg)"); | 80 | IADD(*this, insn, GetReg20(insn)); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | void TranslatorVisitor::IADD_cbuf(u64 insn) { | 83 | void TranslatorVisitor::IADD_cbuf(u64 insn) { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp index 76c6b5291..1bc9ef363 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp | |||
| @@ -92,8 +92,8 @@ void TranslatorVisitor::ISETP_cbuf(u64 insn) { | |||
| 92 | ISETP(*this, insn, GetCbuf(insn)); | 92 | ISETP(*this, insn, GetCbuf(insn)); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | void TranslatorVisitor::ISETP_imm(u64) { | 95 | void TranslatorVisitor::ISETP_imm(u64 insn) { |
| 96 | throw NotImplementedException("ISETP_imm"); | 96 | ISETP(*this, insn, GetImm20(insn)); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | } // namespace Shader::Maxwell | 99 | } // namespace Shader::Maxwell |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index 9fba6ac23..cbde65b9b 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -32,6 +32,8 @@ template <typename T> | |||
| 32 | return value.U1(); | 32 | return value.U1(); |
| 33 | } else if constexpr (std::is_same_v<T, u32>) { | 33 | } else if constexpr (std::is_same_v<T, u32>) { |
| 34 | return value.U32(); | 34 | return value.U32(); |
| 35 | } else if constexpr (std::is_same_v<T, s32>) { | ||
| 36 | return static_cast<s32>(value.U32()); | ||
| 35 | } else if constexpr (std::is_same_v<T, f32>) { | 37 | } else if constexpr (std::is_same_v<T, f32>) { |
| 36 | return value.F32(); | 38 | return value.F32(); |
| 37 | } else if constexpr (std::is_same_v<T, u64>) { | 39 | } else if constexpr (std::is_same_v<T, u64>) { |
| @@ -39,17 +41,8 @@ template <typename T> | |||
| 39 | } | 41 | } |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | template <typename ImmFn> | 44 | template <typename T, typename ImmFn> |
| 43 | bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) { | 45 | bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) { |
| 44 | const auto arg = [](const IR::Value& value) { | ||
| 45 | if constexpr (std::is_invocable_r_v<bool, ImmFn, bool, bool>) { | ||
| 46 | return value.U1(); | ||
| 47 | } else if constexpr (std::is_invocable_r_v<u32, ImmFn, u32, u32>) { | ||
| 48 | return value.U32(); | ||
| 49 | } else if constexpr (std::is_invocable_r_v<u64, ImmFn, u64, u64>) { | ||
| 50 | return value.U64(); | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | const IR::Value lhs{inst.Arg(0)}; | 46 | const IR::Value lhs{inst.Arg(0)}; |
| 54 | const IR::Value rhs{inst.Arg(1)}; | 47 | const IR::Value rhs{inst.Arg(1)}; |
| 55 | 48 | ||
| @@ -57,14 +50,14 @@ bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) { | |||
| 57 | const bool is_rhs_immediate{rhs.IsImmediate()}; | 50 | const bool is_rhs_immediate{rhs.IsImmediate()}; |
| 58 | 51 | ||
| 59 | if (is_lhs_immediate && is_rhs_immediate) { | 52 | if (is_lhs_immediate && is_rhs_immediate) { |
| 60 | const auto result{imm_fn(arg(lhs), arg(rhs))}; | 53 | const auto result{imm_fn(Arg<T>(lhs), Arg<T>(rhs))}; |
| 61 | inst.ReplaceUsesWith(IR::Value{result}); | 54 | inst.ReplaceUsesWith(IR::Value{result}); |
| 62 | return false; | 55 | return false; |
| 63 | } | 56 | } |
| 64 | if (is_lhs_immediate && !is_rhs_immediate) { | 57 | if (is_lhs_immediate && !is_rhs_immediate) { |
| 65 | IR::Inst* const rhs_inst{rhs.InstRecursive()}; | 58 | IR::Inst* const rhs_inst{rhs.InstRecursive()}; |
| 66 | if (rhs_inst->Opcode() == inst.Opcode() && rhs_inst->Arg(1).IsImmediate()) { | 59 | if (rhs_inst->Opcode() == inst.Opcode() && rhs_inst->Arg(1).IsImmediate()) { |
| 67 | const auto combined{imm_fn(arg(lhs), arg(rhs_inst->Arg(1)))}; | 60 | const auto combined{imm_fn(Arg<T>(lhs), Arg<T>(rhs_inst->Arg(1)))}; |
| 68 | inst.SetArg(0, rhs_inst->Arg(0)); | 61 | inst.SetArg(0, rhs_inst->Arg(0)); |
| 69 | inst.SetArg(1, IR::Value{combined}); | 62 | inst.SetArg(1, IR::Value{combined}); |
| 70 | } else { | 63 | } else { |
| @@ -76,7 +69,7 @@ bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) { | |||
| 76 | if (!is_lhs_immediate && is_rhs_immediate) { | 69 | if (!is_lhs_immediate && is_rhs_immediate) { |
| 77 | const IR::Inst* const lhs_inst{lhs.InstRecursive()}; | 70 | const IR::Inst* const lhs_inst{lhs.InstRecursive()}; |
| 78 | if (lhs_inst->Opcode() == inst.Opcode() && lhs_inst->Arg(1).IsImmediate()) { | 71 | if (lhs_inst->Opcode() == inst.Opcode() && lhs_inst->Arg(1).IsImmediate()) { |
| 79 | const auto combined{imm_fn(arg(rhs), arg(lhs_inst->Arg(1)))}; | 72 | const auto combined{imm_fn(Arg<T>(rhs), Arg<T>(lhs_inst->Arg(1)))}; |
| 80 | inst.SetArg(0, lhs_inst->Arg(0)); | 73 | inst.SetArg(0, lhs_inst->Arg(0)); |
| 81 | inst.SetArg(1, IR::Value{combined}); | 74 | inst.SetArg(1, IR::Value{combined}); |
| 82 | } | 75 | } |
| @@ -101,7 +94,7 @@ void FoldAdd(IR::Inst& inst) { | |||
| 101 | if (inst.HasAssociatedPseudoOperation()) { | 94 | if (inst.HasAssociatedPseudoOperation()) { |
| 102 | return; | 95 | return; |
| 103 | } | 96 | } |
| 104 | if (!FoldCommutative(inst, [](T a, T b) { return a + b; })) { | 97 | if (!FoldCommutative<T>(inst, [](T a, T b) { return a + b; })) { |
| 105 | return; | 98 | return; |
| 106 | } | 99 | } |
| 107 | const IR::Value rhs{inst.Arg(1)}; | 100 | const IR::Value rhs{inst.Arg(1)}; |
| @@ -119,7 +112,7 @@ void FoldSelect(IR::Inst& inst) { | |||
| 119 | } | 112 | } |
| 120 | 113 | ||
| 121 | void FoldLogicalAnd(IR::Inst& inst) { | 114 | void FoldLogicalAnd(IR::Inst& inst) { |
| 122 | if (!FoldCommutative(inst, [](bool a, bool b) { return a && b; })) { | 115 | if (!FoldCommutative<bool>(inst, [](bool a, bool b) { return a && b; })) { |
| 123 | return; | 116 | return; |
| 124 | } | 117 | } |
| 125 | const IR::Value rhs{inst.Arg(1)}; | 118 | const IR::Value rhs{inst.Arg(1)}; |
| @@ -133,7 +126,7 @@ void FoldLogicalAnd(IR::Inst& inst) { | |||
| 133 | } | 126 | } |
| 134 | 127 | ||
| 135 | void FoldLogicalOr(IR::Inst& inst) { | 128 | void FoldLogicalOr(IR::Inst& inst) { |
| 136 | if (!FoldCommutative(inst, [](bool a, bool b) { return a || b; })) { | 129 | if (!FoldCommutative<bool>(inst, [](bool a, bool b) { return a || b; })) { |
| 137 | return; | 130 | return; |
| 138 | } | 131 | } |
| 139 | const IR::Value rhs{inst.Arg(1)}; | 132 | const IR::Value rhs{inst.Arg(1)}; |
| @@ -226,6 +219,8 @@ void ConstantPropagation(IR::Inst& inst) { | |||
| 226 | return FoldLogicalOr(inst); | 219 | return FoldLogicalOr(inst); |
| 227 | case IR::Opcode::LogicalNot: | 220 | case IR::Opcode::LogicalNot: |
| 228 | return FoldLogicalNot(inst); | 221 | return FoldLogicalNot(inst); |
| 222 | case IR::Opcode::SLessThan: | ||
| 223 | return FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return a < b; }); | ||
| 229 | case IR::Opcode::ULessThan: | 224 | case IR::Opcode::ULessThan: |
| 230 | return FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a < b; }); | 225 | return FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a < b; }); |
| 231 | case IR::Opcode::BitFieldUExtract: | 226 | case IR::Opcode::BitFieldUExtract: |
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 8ca996e93..7eaf719c4 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -113,6 +113,7 @@ private: | |||
| 113 | IR::Value ReadVariableRecursive(auto variable, IR::Block* block) { | 113 | IR::Value ReadVariableRecursive(auto variable, IR::Block* block) { |
| 114 | IR::Value val; | 114 | IR::Value val; |
| 115 | if (const std::span preds{block->ImmediatePredecessors()}; preds.size() == 1) { | 115 | if (const std::span preds{block->ImmediatePredecessors()}; preds.size() == 1) { |
| 116 | // Optimize the common case of one predecessor: no phi needed | ||
| 116 | val = ReadVariable(variable, preds.front()); | 117 | val = ReadVariable(variable, preds.front()); |
| 117 | } else { | 118 | } else { |
| 118 | // Break potential cycles with operandless phi | 119 | // Break potential cycles with operandless phi |
| @@ -160,66 +161,70 @@ private: | |||
| 160 | 161 | ||
| 161 | DefTable current_def; | 162 | DefTable current_def; |
| 162 | }; | 163 | }; |
| 164 | |||
| 165 | void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | ||
| 166 | switch (inst.Opcode()) { | ||
| 167 | case IR::Opcode::SetRegister: | ||
| 168 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | ||
| 169 | pass.WriteVariable(reg, block, inst.Arg(1)); | ||
| 170 | } | ||
| 171 | break; | ||
| 172 | case IR::Opcode::SetPred: | ||
| 173 | if (const IR::Pred pred{inst.Arg(0).Pred()}; pred != IR::Pred::PT) { | ||
| 174 | pass.WriteVariable(pred, block, inst.Arg(1)); | ||
| 175 | } | ||
| 176 | break; | ||
| 177 | case IR::Opcode::SetGotoVariable: | ||
| 178 | pass.WriteVariable(GotoVariable{inst.Arg(0).U32()}, block, inst.Arg(1)); | ||
| 179 | break; | ||
| 180 | case IR::Opcode::SetZFlag: | ||
| 181 | pass.WriteVariable(ZeroFlagTag{}, block, inst.Arg(0)); | ||
| 182 | break; | ||
| 183 | case IR::Opcode::SetSFlag: | ||
| 184 | pass.WriteVariable(SignFlagTag{}, block, inst.Arg(0)); | ||
| 185 | break; | ||
| 186 | case IR::Opcode::SetCFlag: | ||
| 187 | pass.WriteVariable(CarryFlagTag{}, block, inst.Arg(0)); | ||
| 188 | break; | ||
| 189 | case IR::Opcode::SetOFlag: | ||
| 190 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); | ||
| 191 | break; | ||
| 192 | case IR::Opcode::GetRegister: | ||
| 193 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | ||
| 194 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); | ||
| 195 | } | ||
| 196 | break; | ||
| 197 | case IR::Opcode::GetPred: | ||
| 198 | if (const IR::Pred pred{inst.Arg(0).Pred()}; pred != IR::Pred::PT) { | ||
| 199 | inst.ReplaceUsesWith(pass.ReadVariable(pred, block)); | ||
| 200 | } | ||
| 201 | break; | ||
| 202 | case IR::Opcode::GetGotoVariable: | ||
| 203 | inst.ReplaceUsesWith(pass.ReadVariable(GotoVariable{inst.Arg(0).U32()}, block)); | ||
| 204 | break; | ||
| 205 | case IR::Opcode::GetZFlag: | ||
| 206 | inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block)); | ||
| 207 | break; | ||
| 208 | case IR::Opcode::GetSFlag: | ||
| 209 | inst.ReplaceUsesWith(pass.ReadVariable(SignFlagTag{}, block)); | ||
| 210 | break; | ||
| 211 | case IR::Opcode::GetCFlag: | ||
| 212 | inst.ReplaceUsesWith(pass.ReadVariable(CarryFlagTag{}, block)); | ||
| 213 | break; | ||
| 214 | case IR::Opcode::GetOFlag: | ||
| 215 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | } | ||
| 163 | } // Anonymous namespace | 221 | } // Anonymous namespace |
| 164 | 222 | ||
| 165 | void SsaRewritePass(IR::Function& function) { | 223 | void SsaRewritePass(IR::Function& function) { |
| 166 | Pass pass; | 224 | Pass pass; |
| 167 | for (IR::Block* const block : function.blocks) { | 225 | for (IR::Block* const block : function.blocks) { |
| 168 | for (IR::Inst& inst : block->Instructions()) { | 226 | for (IR::Inst& inst : block->Instructions()) { |
| 169 | switch (inst.Opcode()) { | 227 | VisitInst(pass, block, inst); |
| 170 | case IR::Opcode::SetRegister: | ||
| 171 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | ||
| 172 | pass.WriteVariable(reg, block, inst.Arg(1)); | ||
| 173 | } | ||
| 174 | break; | ||
| 175 | case IR::Opcode::SetPred: | ||
| 176 | if (const IR::Pred pred{inst.Arg(0).Pred()}; pred != IR::Pred::PT) { | ||
| 177 | pass.WriteVariable(pred, block, inst.Arg(1)); | ||
| 178 | } | ||
| 179 | break; | ||
| 180 | case IR::Opcode::SetGotoVariable: | ||
| 181 | pass.WriteVariable(GotoVariable{inst.Arg(0).U32()}, block, inst.Arg(1)); | ||
| 182 | break; | ||
| 183 | case IR::Opcode::SetZFlag: | ||
| 184 | pass.WriteVariable(ZeroFlagTag{}, block, inst.Arg(0)); | ||
| 185 | break; | ||
| 186 | case IR::Opcode::SetSFlag: | ||
| 187 | pass.WriteVariable(SignFlagTag{}, block, inst.Arg(0)); | ||
| 188 | break; | ||
| 189 | case IR::Opcode::SetCFlag: | ||
| 190 | pass.WriteVariable(CarryFlagTag{}, block, inst.Arg(0)); | ||
| 191 | break; | ||
| 192 | case IR::Opcode::SetOFlag: | ||
| 193 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); | ||
| 194 | break; | ||
| 195 | case IR::Opcode::GetRegister: | ||
| 196 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | ||
| 197 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); | ||
| 198 | } | ||
| 199 | break; | ||
| 200 | case IR::Opcode::GetPred: | ||
| 201 | if (const IR::Pred pred{inst.Arg(0).Pred()}; pred != IR::Pred::PT) { | ||
| 202 | inst.ReplaceUsesWith(pass.ReadVariable(pred, block)); | ||
| 203 | } | ||
| 204 | break; | ||
| 205 | case IR::Opcode::GetGotoVariable: | ||
| 206 | inst.ReplaceUsesWith(pass.ReadVariable(GotoVariable{inst.Arg(0).U32()}, block)); | ||
| 207 | break; | ||
| 208 | case IR::Opcode::GetZFlag: | ||
| 209 | inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block)); | ||
| 210 | break; | ||
| 211 | case IR::Opcode::GetSFlag: | ||
| 212 | inst.ReplaceUsesWith(pass.ReadVariable(SignFlagTag{}, block)); | ||
| 213 | break; | ||
| 214 | case IR::Opcode::GetCFlag: | ||
| 215 | inst.ReplaceUsesWith(pass.ReadVariable(CarryFlagTag{}, block)); | ||
| 216 | break; | ||
| 217 | case IR::Opcode::GetOFlag: | ||
| 218 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); | ||
| 219 | break; | ||
| 220 | default: | ||
| 221 | break; | ||
| 222 | } | ||
| 223 | } | 228 | } |
| 224 | } | 229 | } |
| 225 | } | 230 | } |
diff --git a/src/shader_recompiler/main.cpp b/src/shader_recompiler/main.cpp index 3ca1677c4..92358232c 100644 --- a/src/shader_recompiler/main.cpp +++ b/src/shader_recompiler/main.cpp | |||
| @@ -38,7 +38,8 @@ void RunDatabase() { | |||
| 38 | map.emplace_back(std::make_unique<FileEnvironment>(path.string().c_str())); | 38 | map.emplace_back(std::make_unique<FileEnvironment>(path.string().c_str())); |
| 39 | }); | 39 | }); |
| 40 | auto block_pool{std::make_unique<ObjectPool<Flow::Block>>()}; | 40 | auto block_pool{std::make_unique<ObjectPool<Flow::Block>>()}; |
| 41 | auto t0 = std::chrono::high_resolution_clock::now(); | 41 | using namespace std::chrono; |
| 42 | auto t0 = high_resolution_clock::now(); | ||
| 42 | int N = 1; | 43 | int N = 1; |
| 43 | int n = 0; | 44 | int n = 0; |
| 44 | for (int i = 0; i < N; ++i) { | 45 | for (int i = 0; i < N; ++i) { |
| @@ -55,9 +56,8 @@ void RunDatabase() { | |||
| 55 | // const std::string code{EmitGLASM(program)}; | 56 | // const std::string code{EmitGLASM(program)}; |
| 56 | } | 57 | } |
| 57 | } | 58 | } |
| 58 | auto t = std::chrono::high_resolution_clock::now(); | 59 | auto t = high_resolution_clock::now(); |
| 59 | fmt::print(stdout, "{} ms", | 60 | fmt::print(stdout, "{} ms", duration_cast<milliseconds>(t - t0).count() / double(N)); |
| 60 | std::chrono::duration_cast<std::chrono::milliseconds>(t - t0).count() / double(N)); | ||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | int main() { | 63 | int main() { |
| @@ -67,8 +67,8 @@ int main() { | |||
| 67 | auto inst_pool{std::make_unique<ObjectPool<IR::Inst>>()}; | 67 | auto inst_pool{std::make_unique<ObjectPool<IR::Inst>>()}; |
| 68 | auto block_pool{std::make_unique<ObjectPool<IR::Block>>()}; | 68 | auto block_pool{std::make_unique<ObjectPool<IR::Block>>()}; |
| 69 | 69 | ||
| 70 | FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS8F146B41DB6BD826.bin"}; | 70 | // FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS8F146B41DB6BD826.bin"}; |
| 71 | // FileEnvironment env{"D:\\Shaders\\shader.bin"}; | 71 | FileEnvironment env{"D:\\Shaders\\shader.bin"}; |
| 72 | for (int i = 0; i < 1; ++i) { | 72 | for (int i = 0; i < 1; ++i) { |
| 73 | block_pool->ReleaseContents(); | 73 | block_pool->ReleaseContents(); |
| 74 | inst_pool->ReleaseContents(); | 74 | inst_pool->ReleaseContents(); |