diff options
| author | 2021-02-11 16:39:06 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 9170200a11715d131645d1ffb92e86e6ef0d7e88 (patch) | |
| tree | 6c6f84c38a9b59d023ecb09c0737ea56da166b64 /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |
| parent | spirv: Initial SPIR-V support (diff) | |
| download | yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.gz yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.xz yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.zip | |
shader: Initial implementation of an AST
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index f1170c61e..9fba6ac23 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -132,6 +132,32 @@ void FoldLogicalAnd(IR::Inst& inst) { | |||
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | void FoldLogicalOr(IR::Inst& inst) { | ||
| 136 | if (!FoldCommutative(inst, [](bool a, bool b) { return a || b; })) { | ||
| 137 | return; | ||
| 138 | } | ||
| 139 | const IR::Value rhs{inst.Arg(1)}; | ||
| 140 | if (rhs.IsImmediate()) { | ||
| 141 | if (rhs.U1()) { | ||
| 142 | inst.ReplaceUsesWith(IR::Value{true}); | ||
| 143 | } else { | ||
| 144 | inst.ReplaceUsesWith(inst.Arg(0)); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | void FoldLogicalNot(IR::Inst& inst) { | ||
| 150 | const IR::U1 value{inst.Arg(0)}; | ||
| 151 | if (value.IsImmediate()) { | ||
| 152 | inst.ReplaceUsesWith(IR::Value{!value.U1()}); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | IR::Inst* const arg{value.InstRecursive()}; | ||
| 156 | if (arg->Opcode() == IR::Opcode::LogicalNot) { | ||
| 157 | inst.ReplaceUsesWith(arg->Arg(0)); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 135 | template <typename Dest, typename Source> | 161 | template <typename Dest, typename Source> |
| 136 | void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { | 162 | void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { |
| 137 | const IR::Value value{inst.Arg(0)}; | 163 | const IR::Value value{inst.Arg(0)}; |
| @@ -160,6 +186,24 @@ void FoldWhenAllImmediates(IR::Inst& inst, Func&& func) { | |||
| 160 | inst.ReplaceUsesWith(EvalImmediates(inst, func, Indices{})); | 186 | inst.ReplaceUsesWith(EvalImmediates(inst, func, Indices{})); |
| 161 | } | 187 | } |
| 162 | 188 | ||
| 189 | void FoldBranchConditional(IR::Inst& inst) { | ||
| 190 | const IR::U1 cond{inst.Arg(0)}; | ||
| 191 | if (cond.IsImmediate()) { | ||
| 192 | // TODO: Convert to Branch | ||
| 193 | return; | ||
| 194 | } | ||
| 195 | const IR::Inst* cond_inst{cond.InstRecursive()}; | ||
| 196 | if (cond_inst->Opcode() == IR::Opcode::LogicalNot) { | ||
| 197 | const IR::Value true_label{inst.Arg(1)}; | ||
| 198 | const IR::Value false_label{inst.Arg(2)}; | ||
| 199 | // Remove negation on the conditional (take the parameter out of LogicalNot) and swap | ||
| 200 | // the branches | ||
| 201 | inst.SetArg(0, cond_inst->Arg(0)); | ||
| 202 | inst.SetArg(1, false_label); | ||
| 203 | inst.SetArg(2, true_label); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 163 | void ConstantPropagation(IR::Inst& inst) { | 207 | void ConstantPropagation(IR::Inst& inst) { |
| 164 | switch (inst.Opcode()) { | 208 | switch (inst.Opcode()) { |
| 165 | case IR::Opcode::GetRegister: | 209 | case IR::Opcode::GetRegister: |
| @@ -178,6 +222,10 @@ void ConstantPropagation(IR::Inst& inst) { | |||
| 178 | return FoldSelect<u32>(inst); | 222 | return FoldSelect<u32>(inst); |
| 179 | case IR::Opcode::LogicalAnd: | 223 | case IR::Opcode::LogicalAnd: |
| 180 | return FoldLogicalAnd(inst); | 224 | return FoldLogicalAnd(inst); |
| 225 | case IR::Opcode::LogicalOr: | ||
| 226 | return FoldLogicalOr(inst); | ||
| 227 | case IR::Opcode::LogicalNot: | ||
| 228 | return FoldLogicalNot(inst); | ||
| 181 | case IR::Opcode::ULessThan: | 229 | case IR::Opcode::ULessThan: |
| 182 | return FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a < b; }); | 230 | return FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a < b; }); |
| 183 | case IR::Opcode::BitFieldUExtract: | 231 | case IR::Opcode::BitFieldUExtract: |
| @@ -188,6 +236,8 @@ void ConstantPropagation(IR::Inst& inst) { | |||
| 188 | } | 236 | } |
| 189 | return (base >> shift) & ((1U << count) - 1); | 237 | return (base >> shift) & ((1U << count) - 1); |
| 190 | }); | 238 | }); |
| 239 | case IR::Opcode::BranchConditional: | ||
| 240 | return FoldBranchConditional(inst); | ||
| 191 | default: | 241 | default: |
| 192 | break; | 242 | break; |
| 193 | } | 243 | } |