diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/basic_block.h | 9 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 5 |
2 files changed, 11 insertions, 3 deletions
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h index ab7ddb3d5..0b0c97af6 100644 --- a/src/shader_recompiler/frontend/ir/basic_block.h +++ b/src/shader_recompiler/frontend/ir/basic_block.h | |||
| @@ -107,6 +107,13 @@ public: | |||
| 107 | return ssa_reg_values[RegIndex(reg)]; | 107 | return ssa_reg_values[RegIndex(reg)]; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | void SsaSeal() noexcept { | ||
| 111 | is_ssa_sealed = true; | ||
| 112 | } | ||
| 113 | [[nodiscard]] bool IsSsaSealed() const noexcept { | ||
| 114 | return is_ssa_sealed; | ||
| 115 | } | ||
| 116 | |||
| 110 | [[nodiscard]] bool empty() const { | 117 | [[nodiscard]] bool empty() const { |
| 111 | return instructions.empty(); | 118 | return instructions.empty(); |
| 112 | } | 119 | } |
| @@ -190,6 +197,8 @@ private: | |||
| 190 | 197 | ||
| 191 | /// Intrusively store the value of a register in the block. | 198 | /// Intrusively store the value of a register in the block. |
| 192 | std::array<Value, NUM_REGS> ssa_reg_values; | 199 | std::array<Value, NUM_REGS> ssa_reg_values; |
| 200 | /// Intrusively store if the block is sealed in the SSA pass. | ||
| 201 | bool is_ssa_sealed{false}; | ||
| 193 | 202 | ||
| 194 | /// Intrusively stored host definition of this block. | 203 | /// Intrusively stored host definition of this block. |
| 195 | u32 definition{}; | 204 | u32 definition{}; |
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index fe86a164b..3bab742e7 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -195,7 +195,7 @@ public: | |||
| 195 | case Status::Start: { | 195 | case Status::Start: { |
| 196 | if (const IR::Value& def = current_def.Def(block, variable); !def.IsEmpty()) { | 196 | if (const IR::Value& def = current_def.Def(block, variable); !def.IsEmpty()) { |
| 197 | stack.back().result = def; | 197 | stack.back().result = def; |
| 198 | } else if (!sealed_blocks.contains(block)) { | 198 | } else if (!block->IsSsaSealed()) { |
| 199 | // Incomplete CFG | 199 | // Incomplete CFG |
| 200 | IR::Inst* phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)}; | 200 | IR::Inst* phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)}; |
| 201 | phi->SetFlags(IR::TypeOf(UndefOpcode(variable))); | 201 | phi->SetFlags(IR::TypeOf(UndefOpcode(variable))); |
| @@ -251,7 +251,7 @@ public: | |||
| 251 | std::visit([&](auto& variable) { AddPhiOperands(variable, *phi, block); }, variant); | 251 | std::visit([&](auto& variable) { AddPhiOperands(variable, *phi, block); }, variant); |
| 252 | } | 252 | } |
| 253 | } | 253 | } |
| 254 | sealed_blocks.insert(block); | 254 | block->SsaSeal(); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | private: | 257 | private: |
| @@ -297,7 +297,6 @@ private: | |||
| 297 | return same; | 297 | return same; |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | boost::container::flat_set<IR::Block*> sealed_blocks; | ||
| 301 | boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>> | 300 | boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>> |
| 302 | incomplete_phis; | 301 | incomplete_phis; |
| 303 | DefTable current_def; | 302 | DefTable current_def; |