summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-21 00:27:55 -0300
committerGravatar ameerj2021-07-22 21:51:28 -0400
commit420982864634a5e52cea42c43f8623f75483fbcc (patch)
tree5433936232c2819713e69581641ce271c4e0e68f /src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
parentshader: Inline common Opcode and Inst functions (diff)
downloadyuzu-420982864634a5e52cea42c43f8623f75483fbcc.tar.gz
yuzu-420982864634a5e52cea42c43f8623f75483fbcc.tar.xz
yuzu-420982864634a5e52cea42c43f8623f75483fbcc.zip
shader: Intrusively store register values in block for SSA pass
Diffstat (limited to 'src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp64
1 files changed, 43 insertions, 21 deletions
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index ddd679e39..bb1a90004 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -57,39 +57,62 @@ using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryF
57using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; 57using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
58 58
59struct DefTable { 59struct DefTable {
60 [[nodiscard]] ValueMap& operator[](IR::Reg variable) noexcept { 60 const IR::Value& Def(IR::Block* block, IR::Reg variable) noexcept {
61 return regs[IR::RegIndex(variable)]; 61 return block->SsaRegValue(variable);
62 }
63 void SetDef(IR::Block* block, IR::Reg variable, const IR::Value& value) noexcept {
64 block->SetSsaRegValue(variable, value);
62 } 65 }
63 66
64 [[nodiscard]] ValueMap& operator[](IR::Pred variable) noexcept { 67 const IR::Value& Def(IR::Block* block, IR::Pred variable) noexcept {
65 return preds[IR::PredIndex(variable)]; 68 return preds[IR::PredIndex(variable)][block];
69 }
70 void SetDef(IR::Block* block, IR::Pred variable, const IR::Value& value) noexcept {
71 preds[IR::PredIndex(variable)].insert_or_assign(block, value);
66 } 72 }
67 73
68 [[nodiscard]] ValueMap& operator[](GotoVariable goto_variable) { 74 const IR::Value& Def(IR::Block* block, GotoVariable variable) noexcept {
69 return goto_vars[goto_variable.index]; 75 return goto_vars[variable.index][block];
76 }
77 void SetDef(IR::Block* block, GotoVariable variable, const IR::Value& value) noexcept {
78 goto_vars[variable.index].insert_or_assign(block, value);
70 } 79 }
71 80
72 [[nodiscard]] ValueMap& operator[](IndirectBranchVariable) { 81 const IR::Value& Def(IR::Block* block, IndirectBranchVariable) noexcept {
73 return indirect_branch_var; 82 return indirect_branch_var[block];
83 }
84 void SetDef(IR::Block* block, IndirectBranchVariable, const IR::Value& value) noexcept {
85 indirect_branch_var.insert_or_assign(block, value);
74 } 86 }
75 87
76 [[nodiscard]] ValueMap& operator[](ZeroFlagTag) noexcept { 88 const IR::Value& Def(IR::Block* block, ZeroFlagTag) noexcept {
77 return zero_flag; 89 return zero_flag[block];
90 }
91 void SetDef(IR::Block* block, ZeroFlagTag, const IR::Value& value) noexcept {
92 zero_flag.insert_or_assign(block, value);
78 } 93 }
79 94
80 [[nodiscard]] ValueMap& operator[](SignFlagTag) noexcept { 95 const IR::Value& Def(IR::Block* block, SignFlagTag) noexcept {
81 return sign_flag; 96 return sign_flag[block];
97 }
98 void SetDef(IR::Block* block, SignFlagTag, const IR::Value& value) noexcept {
99 sign_flag.insert_or_assign(block, value);
82 } 100 }
83 101
84 [[nodiscard]] ValueMap& operator[](CarryFlagTag) noexcept { 102 const IR::Value& Def(IR::Block* block, CarryFlagTag) noexcept {
85 return carry_flag; 103 return carry_flag[block];
104 }
105 void SetDef(IR::Block* block, CarryFlagTag, const IR::Value& value) noexcept {
106 carry_flag.insert_or_assign(block, value);
86 } 107 }
87 108
88 [[nodiscard]] ValueMap& operator[](OverflowFlagTag) noexcept { 109 const IR::Value& Def(IR::Block* block, OverflowFlagTag) noexcept {
89 return overflow_flag; 110 return overflow_flag[block];
111 }
112 void SetDef(IR::Block* block, OverflowFlagTag, const IR::Value& value) noexcept {
113 overflow_flag.insert_or_assign(block, value);
90 } 114 }
91 115
92 std::array<ValueMap, IR::NUM_USER_REGS> regs;
93 std::array<ValueMap, IR::NUM_USER_PREDS> preds; 116 std::array<ValueMap, IR::NUM_USER_PREDS> preds;
94 boost::container::flat_map<u32, ValueMap> goto_vars; 117 boost::container::flat_map<u32, ValueMap> goto_vars;
95 ValueMap indirect_branch_var; 118 ValueMap indirect_branch_var;
@@ -143,7 +166,7 @@ class Pass {
143public: 166public:
144 template <typename Type> 167 template <typename Type>
145 void WriteVariable(Type variable, IR::Block* block, const IR::Value& value) { 168 void WriteVariable(Type variable, IR::Block* block, const IR::Value& value) {
146 current_def[variable].insert_or_assign(block, value); 169 current_def.SetDef(block, variable, value);
147 } 170 }
148 171
149 template <typename Type> 172 template <typename Type>
@@ -170,9 +193,8 @@ public:
170 IR::Block* const block{stack.back().block}; 193 IR::Block* const block{stack.back().block};
171 switch (stack.back().pc) { 194 switch (stack.back().pc) {
172 case Status::Start: { 195 case Status::Start: {
173 const ValueMap& def{current_def[variable]}; 196 if (const IR::Value& def = current_def.Def(block, variable); !def.IsEmpty()) {
174 if (const auto it{def.find(block)}; it != def.end()) { 197 stack.back().result = def;
175 stack.back().result = it->second;
176 } else if (!sealed_blocks.contains(block)) { 198 } else if (!sealed_blocks.contains(block)) {
177 // Incomplete CFG 199 // Incomplete CFG
178 IR::Inst* phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)}; 200 IR::Inst* phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)};