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/ssa_rewrite_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/ssa_rewrite_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 113 |
1 files changed, 59 insertions, 54 deletions
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 | } |