diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
4 files changed, 34 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h index 7e134b4c7..9ce1ed07e 100644 --- a/src/shader_recompiler/frontend/ir/basic_block.h +++ b/src/shader_recompiler/frontend/ir/basic_block.h | |||
| @@ -152,6 +152,17 @@ public: | |||
| 152 | return instructions.crend(); | 152 | return instructions.crend(); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | // Set the order of the block, it can be set pre order, the user decides | ||
| 156 | void SetOrder(u32 new_order) { | ||
| 157 | order = new_order; | ||
| 158 | } | ||
| 159 | |||
| 160 | // Get the order of the block. | ||
| 161 | // The higher, the closer is the block to the end. | ||
| 162 | [[nodiscard]] u32 GetOrder() const { | ||
| 163 | return order; | ||
| 164 | } | ||
| 165 | |||
| 155 | private: | 166 | private: |
| 156 | /// Memory pool for instruction list | 167 | /// Memory pool for instruction list |
| 157 | ObjectPool<Inst>* inst_pool; | 168 | ObjectPool<Inst>* inst_pool; |
| @@ -171,6 +182,9 @@ private: | |||
| 171 | 182 | ||
| 172 | /// Intrusively stored host definition of this block. | 183 | /// Intrusively stored host definition of this block. |
| 173 | u32 definition{}; | 184 | u32 definition{}; |
| 185 | |||
| 186 | /// Order of the block. | ||
| 187 | u32 order{}; | ||
| 174 | }; | 188 | }; |
| 175 | 189 | ||
| 176 | using BlockList = std::vector<Block*>; | 190 | using BlockList = std::vector<Block*>; |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 3dfa5a880..30b470bdd 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | 7 | ||
| 8 | #include "shader_recompiler/exception.h" | 8 | #include "shader_recompiler/exception.h" |
| 9 | #include "shader_recompiler/frontend/ir/basic_block.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/type.h" | 10 | #include "shader_recompiler/frontend/ir/type.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 11 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 12 | ||
| @@ -253,6 +254,10 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { | |||
| 253 | } | 254 | } |
| 254 | 255 | ||
| 255 | IR::Type Inst::Type() const { | 256 | IR::Type Inst::Type() const { |
| 257 | if (op == IR::Opcode::Phi) { | ||
| 258 | // The type of a phi node is stored in its flags | ||
| 259 | return Flags<IR::Type>(); | ||
| 260 | } | ||
| 256 | return TypeOf(op); | 261 | return TypeOf(op); |
| 257 | } | 262 | } |
| 258 | 263 | ||
| @@ -291,6 +296,16 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) { | |||
| 291 | phi_args.emplace_back(predecessor, value); | 296 | phi_args.emplace_back(predecessor, value); |
| 292 | } | 297 | } |
| 293 | 298 | ||
| 299 | void Inst::OrderPhiArgs() { | ||
| 300 | if (op != Opcode::Phi) { | ||
| 301 | throw LogicError("{} is not a Phi instruction", op); | ||
| 302 | } | ||
| 303 | std::sort(phi_args.begin(), phi_args.end(), | ||
| 304 | [](const std::pair<Block*, Value>& a, const std::pair<Block*, Value>& b) { | ||
| 305 | return a.first->GetOrder() < b.first->GetOrder(); | ||
| 306 | }); | ||
| 307 | } | ||
| 308 | |||
| 294 | void Inst::Invalidate() { | 309 | void Inst::Invalidate() { |
| 295 | ClearArgs(); | 310 | ClearArgs(); |
| 296 | ReplaceOpcode(Opcode::Void); | 311 | ReplaceOpcode(Opcode::Void); |
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 334bb47aa..6c9ef6bdd 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h | |||
| @@ -182,6 +182,9 @@ public: | |||
| 182 | /// Add phi operand to a phi instruction. | 182 | /// Add phi operand to a phi instruction. |
| 183 | void AddPhiOperand(Block* predecessor, const Value& value); | 183 | void AddPhiOperand(Block* predecessor, const Value& value); |
| 184 | 184 | ||
| 185 | /// Orders the Phi arguments from farthest away to nearest. | ||
| 186 | void OrderPhiArgs(); | ||
| 187 | |||
| 185 | void Invalidate(); | 188 | void Invalidate(); |
| 186 | void ClearArgs(); | 189 | void ClearArgs(); |
| 187 | 190 | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 012d55357..2fc542f0e 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp | |||
| @@ -27,9 +27,11 @@ IR::BlockList GenerateBlocks(const IR::AbstractSyntaxList& syntax_list) { | |||
| 27 | } | 27 | } |
| 28 | IR::BlockList blocks; | 28 | IR::BlockList blocks; |
| 29 | blocks.reserve(num_syntax_blocks); | 29 | blocks.reserve(num_syntax_blocks); |
| 30 | u32 order_index{}; | ||
| 30 | for (const auto& node : syntax_list) { | 31 | for (const auto& node : syntax_list) { |
| 31 | if (node.type == IR::AbstractSyntaxNode::Type::Block) { | 32 | if (node.type == IR::AbstractSyntaxNode::Type::Block) { |
| 32 | blocks.push_back(node.data.block); | 33 | blocks.push_back(node.data.block); |
| 34 | blocks.back()->SetOrder(order_index++); | ||
| 33 | } | 35 | } |
| 34 | } | 36 | } |
| 35 | return blocks; | 37 | return blocks; |