diff options
| author | 2021-02-14 01:24:32 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 8af9297f0972d0aaa8306369c5d04926b886a89e (patch) | |
| tree | 43bb3f50d694b615d2ae821eef84e417166d4890 /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |
| parent | shader: Initial implementation of an AST (diff) | |
| download | yuzu-8af9297f0972d0aaa8306369c5d04926b886a89e.tar.gz yuzu-8af9297f0972d0aaa8306369c5d04926b886a89e.tar.xz yuzu-8af9297f0972d0aaa8306369c5d04926b886a89e.zip | |
shader: Misc fixes
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | 27 |
1 files changed, 11 insertions, 16 deletions
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: |