diff options
5 files changed, 37 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: return instructions.crend(); } + // Set the order of the block, it can be set pre order, the user decides + void SetOrder(u32 new_order) { + order = new_order; + } + + // Get the order of the block. + // The higher, the closer is the block to the end. + [[nodiscard]] u32 GetOrder() const { + return order; + } + private: /// Memory pool for instruction list ObjectPool<Inst>* inst_pool; @@ -171,6 +182,9 @@ private: /// Intrusively stored host definition of this block. u32 definition{}; + + /// Order of the block. + u32 order{}; }; 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..e563b4022 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -6,6 +6,7 @@ #include <memory> #include "shader_recompiler/exception.h" +#include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/type.h" #include "shader_recompiler/frontend/ir/value.h" @@ -291,6 +292,16 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) { phi_args.emplace_back(predecessor, value); } +void Inst::OrderPhiArgs() { + if (op != Opcode::Phi) { + throw LogicError("{} is not a Phi instruction", op); + } + std::sort(phi_args.begin(), phi_args.end(), + [](const std::pair<Block*, Value>& a, const std::pair<Block*, Value>& b) { + return a.first->GetOrder() < b.first->GetOrder(); + }); +} + void Inst::Invalidate() { ClearArgs(); 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: /// Add phi operand to a phi instruction. void AddPhiOperand(Block* predecessor, const Value& value); + /// Orders the Phi arguments from farthest away to nearest. + void OrderPhiArgs(); + void Invalidate(); void ClearArgs(); 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) { } IR::BlockList blocks; blocks.reserve(num_syntax_blocks); + u32 order_index{}; for (const auto& node : syntax_list) { if (node.type == IR::AbstractSyntaxNode::Type::Block) { blocks.push_back(node.data.block); + blocks.back()->SetOrder(order_index++); } } return blocks; diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 53145fb5e..5545f8197 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp @@ -378,6 +378,13 @@ void SsaRewritePass(IR::Program& program) { for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { VisitBlock(pass, *block); } + for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { + for (IR::Inst& inst : (*block)->Instructions()) { + if (inst.GetOpcode() == IR::Opcode::Phi) { + inst.OrderPhiArgs(); + } + } + } } } // namespace Shader::Optimization |