diff options
Diffstat (limited to 'src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index bab7ca186..259233746 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -48,8 +48,12 @@ struct GotoVariable : FlagTag { | |||
| 48 | u32 index; | 48 | u32 index; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | struct IndirectBranchVariable { | ||
| 52 | auto operator<=>(const IndirectBranchVariable&) const noexcept = default; | ||
| 53 | }; | ||
| 54 | |||
| 51 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, | 55 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, |
| 52 | OverflowFlagTag, GotoVariable>; | 56 | OverflowFlagTag, GotoVariable, IndirectBranchVariable>; |
| 53 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; | 57 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; |
| 54 | 58 | ||
| 55 | struct DefTable { | 59 | struct DefTable { |
| @@ -65,6 +69,10 @@ struct DefTable { | |||
| 65 | return goto_vars[goto_variable.index]; | 69 | return goto_vars[goto_variable.index]; |
| 66 | } | 70 | } |
| 67 | 71 | ||
| 72 | [[nodiscard]] ValueMap& operator[](IndirectBranchVariable) { | ||
| 73 | return indirect_branch_var; | ||
| 74 | } | ||
| 75 | |||
| 68 | [[nodiscard]] ValueMap& operator[](ZeroFlagTag) noexcept { | 76 | [[nodiscard]] ValueMap& operator[](ZeroFlagTag) noexcept { |
| 69 | return zero_flag; | 77 | return zero_flag; |
| 70 | } | 78 | } |
| @@ -84,6 +92,7 @@ struct DefTable { | |||
| 84 | std::array<ValueMap, IR::NUM_USER_REGS> regs; | 92 | std::array<ValueMap, IR::NUM_USER_REGS> regs; |
| 85 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; | 93 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; |
| 86 | boost::container::flat_map<u32, ValueMap> goto_vars; | 94 | boost::container::flat_map<u32, ValueMap> goto_vars; |
| 95 | ValueMap indirect_branch_var; | ||
| 87 | ValueMap zero_flag; | 96 | ValueMap zero_flag; |
| 88 | ValueMap sign_flag; | 97 | ValueMap sign_flag; |
| 89 | ValueMap carry_flag; | 98 | ValueMap carry_flag; |
| @@ -102,6 +111,10 @@ IR::Opcode UndefOpcode(const FlagTag&) noexcept { | |||
| 102 | return IR::Opcode::UndefU1; | 111 | return IR::Opcode::UndefU1; |
| 103 | } | 112 | } |
| 104 | 113 | ||
| 114 | IR::Opcode UndefOpcode(IndirectBranchVariable) noexcept { | ||
| 115 | return IR::Opcode::UndefU32; | ||
| 116 | } | ||
| 117 | |||
| 105 | [[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept { | 118 | [[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept { |
| 106 | return inst.Opcode() == IR::Opcode::Phi; | 119 | return inst.Opcode() == IR::Opcode::Phi; |
| 107 | } | 120 | } |
| @@ -219,6 +232,9 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 219 | case IR::Opcode::SetGotoVariable: | 232 | case IR::Opcode::SetGotoVariable: |
| 220 | pass.WriteVariable(GotoVariable{inst.Arg(0).U32()}, block, inst.Arg(1)); | 233 | pass.WriteVariable(GotoVariable{inst.Arg(0).U32()}, block, inst.Arg(1)); |
| 221 | break; | 234 | break; |
| 235 | case IR::Opcode::SetIndirectBranchVariable: | ||
| 236 | pass.WriteVariable(IndirectBranchVariable{}, block, inst.Arg(0)); | ||
| 237 | break; | ||
| 222 | case IR::Opcode::SetZFlag: | 238 | case IR::Opcode::SetZFlag: |
| 223 | pass.WriteVariable(ZeroFlagTag{}, block, inst.Arg(0)); | 239 | pass.WriteVariable(ZeroFlagTag{}, block, inst.Arg(0)); |
| 224 | break; | 240 | break; |
| @@ -244,6 +260,9 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 244 | case IR::Opcode::GetGotoVariable: | 260 | case IR::Opcode::GetGotoVariable: |
| 245 | inst.ReplaceUsesWith(pass.ReadVariable(GotoVariable{inst.Arg(0).U32()}, block)); | 261 | inst.ReplaceUsesWith(pass.ReadVariable(GotoVariable{inst.Arg(0).U32()}, block)); |
| 246 | break; | 262 | break; |
| 263 | case IR::Opcode::GetIndirectBranchVariable: | ||
| 264 | inst.ReplaceUsesWith(pass.ReadVariable(IndirectBranchVariable{}, block)); | ||
| 265 | break; | ||
| 247 | case IR::Opcode::GetZFlag: | 266 | case IR::Opcode::GetZFlag: |
| 248 | inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block)); | 267 | inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block)); |
| 249 | break; | 268 | break; |