diff options
| author | 2021-05-14 00:40:54 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:31 -0400 | |
| commit | d54d7de40e7295827b0e4e4026441b53d3fc9569 (patch) | |
| tree | 29b5074f851292dace7aeb5da7716675544b3735 /src/shader_recompiler/ir_opt | |
| parent | glasm: Implement Storage atomics (diff) | |
| download | yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.tar.gz yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.tar.xz yuzu-d54d7de40e7295827b0e4e4026441b53d3fc9569.zip | |
glasm: Rework control flow introducing a syntax list
This commit regresses VertexA shaders, their transformation pass has to
be adapted to the new control flow.
Diffstat (limited to 'src/shader_recompiler/ir_opt')
4 files changed, 8 insertions, 73 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index b1c45d13a..66f1391db 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -353,24 +353,6 @@ IR::Value EvalImmediates(const IR::Inst& inst, Func&& func, std::index_sequence< | |||
| 353 | return IR::Value{func(Arg<typename Traits::template ArgType<I>>(inst.Arg(I))...)}; | 353 | return IR::Value{func(Arg<typename Traits::template ArgType<I>>(inst.Arg(I))...)}; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | void FoldBranchConditional(IR::Inst& inst) { | ||
| 357 | const IR::U1 cond{inst.Arg(0)}; | ||
| 358 | if (cond.IsImmediate()) { | ||
| 359 | // TODO: Convert to Branch | ||
| 360 | return; | ||
| 361 | } | ||
| 362 | const IR::Inst* cond_inst{cond.InstRecursive()}; | ||
| 363 | if (cond_inst->GetOpcode() == IR::Opcode::LogicalNot) { | ||
| 364 | const IR::Value true_label{inst.Arg(1)}; | ||
| 365 | const IR::Value false_label{inst.Arg(2)}; | ||
| 366 | // Remove negation on the conditional (take the parameter out of LogicalNot) and swap | ||
| 367 | // the branches | ||
| 368 | inst.SetArg(0, cond_inst->Arg(0)); | ||
| 369 | inst.SetArg(1, false_label); | ||
| 370 | inst.SetArg(2, true_label); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opcode insert, | 356 | std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opcode insert, |
| 375 | IR::Opcode construct, u32 first_index) { | 357 | IR::Opcode construct, u32 first_index) { |
| 376 | IR::Inst* const inst{inst_value.InstRecursive()}; | 358 | IR::Inst* const inst{inst_value.InstRecursive()}; |
| @@ -581,8 +563,6 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 581 | return (base & ~(~(~0u << bits) << offset)) | (insert << offset); | 563 | return (base & ~(~(~0u << bits) << offset)) | (insert << offset); |
| 582 | }); | 564 | }); |
| 583 | return; | 565 | return; |
| 584 | case IR::Opcode::BranchConditional: | ||
| 585 | return FoldBranchConditional(inst); | ||
| 586 | case IR::Opcode::CompositeExtractF32x2: | 566 | case IR::Opcode::CompositeExtractF32x2: |
| 587 | return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF32x2, | 567 | return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF32x2, |
| 588 | IR::Opcode::CompositeInsertF32x2); | 568 | IR::Opcode::CompositeInsertF32x2); |
diff --git a/src/shader_recompiler/ir_opt/dual_vertex_pass.cpp b/src/shader_recompiler/ir_opt/dual_vertex_pass.cpp index f2d7db0e6..b0a9f5258 100644 --- a/src/shader_recompiler/ir_opt/dual_vertex_pass.cpp +++ b/src/shader_recompiler/ir_opt/dual_vertex_pass.cpp | |||
| @@ -13,60 +13,16 @@ | |||
| 13 | 13 | ||
| 14 | namespace Shader::Optimization { | 14 | namespace Shader::Optimization { |
| 15 | 15 | ||
| 16 | void VertexATransformPass(IR::Program& program) { | 16 | void VertexATransformPass(IR::Program&) { |
| 17 | bool replaced_join{}; | 17 | throw NotImplementedException("VertexA pass"); |
| 18 | bool eliminated_epilogue{}; | ||
| 19 | for (IR::Block* const block : program.post_order_blocks) { | ||
| 20 | for (IR::Inst& inst : block->Instructions()) { | ||
| 21 | switch (inst.GetOpcode()) { | ||
| 22 | case IR::Opcode::Return: | ||
| 23 | inst.ReplaceOpcode(IR::Opcode::Join); | ||
| 24 | replaced_join = true; | ||
| 25 | break; | ||
| 26 | case IR::Opcode::Epilogue: | ||
| 27 | inst.Invalidate(); | ||
| 28 | eliminated_epilogue = true; | ||
| 29 | break; | ||
| 30 | default: | ||
| 31 | break; | ||
| 32 | } | ||
| 33 | if (replaced_join && eliminated_epilogue) { | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | 18 | } |
| 39 | 19 | ||
| 40 | void VertexBTransformPass(IR::Program& program) { | 20 | void VertexBTransformPass(IR::Program&) { |
| 41 | for (IR::Block* const block : program.blocks) { | 21 | throw NotImplementedException("VertexA pass"); |
| 42 | for (IR::Inst& inst : block->Instructions()) { | ||
| 43 | if (inst.GetOpcode() == IR::Opcode::Prologue) { | ||
| 44 | return inst.Invalidate(); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | } | 22 | } |
| 49 | 23 | ||
| 50 | void DualVertexJoinPass(IR::Program& program) { | 24 | void DualVertexJoinPass(IR::Program&) { |
| 51 | const auto& blocks = program.blocks; | 25 | throw NotImplementedException("VertexA pass"); |
| 52 | const s64 sub_size = static_cast<s64>(blocks.size()) - 1; | ||
| 53 | if (sub_size < 1) { | ||
| 54 | throw LogicError("Dual Vertex Join pass failed, expected atleast 2 blocks"); | ||
| 55 | } | ||
| 56 | for (s64 index = 0; index < sub_size; ++index) { | ||
| 57 | IR::Block* const current_block{blocks[index]}; | ||
| 58 | IR::Block* const next_block{blocks[index + 1]}; | ||
| 59 | for (IR::Inst& inst : current_block->Instructions()) { | ||
| 60 | if (inst.GetOpcode() == IR::Opcode::Join) { | ||
| 61 | IR::IREmitter ir{*current_block, IR::Block::InstructionList::s_iterator_to(inst)}; | ||
| 62 | ir.Branch(next_block); | ||
| 63 | inst.Invalidate(); | ||
| 64 | // Only 1 join should exist | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | throw LogicError("Dual Vertex Join pass failed, no join present"); | ||
| 70 | } | 26 | } |
| 71 | 27 | ||
| 72 | } // namespace Shader::Optimization | 28 | } // namespace Shader::Optimization |
diff --git a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp index 6afbe24f7..e9b55f835 100644 --- a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp +++ b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp | |||
| @@ -12,7 +12,6 @@ namespace Shader::Optimization { | |||
| 12 | 12 | ||
| 13 | void IdentityRemovalPass(IR::Program& program) { | 13 | void IdentityRemovalPass(IR::Program& program) { |
| 14 | std::vector<IR::Inst*> to_invalidate; | 14 | std::vector<IR::Inst*> to_invalidate; |
| 15 | |||
| 16 | for (IR::Block* const block : program.blocks) { | 15 | for (IR::Block* const block : program.blocks) { |
| 17 | for (auto inst = block->begin(); inst != block->end();) { | 16 | for (auto inst = block->begin(); inst != block->end();) { |
| 18 | const size_t num_args{inst->NumArgs()}; | 17 | const size_t num_args{inst->NumArgs()}; |
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index a8064a5d0..26eb3a3ab 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -202,7 +202,7 @@ public: | |||
| 202 | 202 | ||
| 203 | incomplete_phis[block].insert_or_assign(variable, phi); | 203 | incomplete_phis[block].insert_or_assign(variable, phi); |
| 204 | stack.back().result = IR::Value{&*phi}; | 204 | stack.back().result = IR::Value{&*phi}; |
| 205 | } else if (const std::span imm_preds{block->ImmediatePredecessors()}; | 205 | } else if (const std::span imm_preds = block->ImmPredecessors(); |
| 206 | imm_preds.size() == 1) { | 206 | imm_preds.size() == 1) { |
| 207 | // Optimize the common case of one predecessor: no phi needed | 207 | // Optimize the common case of one predecessor: no phi needed |
| 208 | stack.back().pc = Status::SetValue; | 208 | stack.back().pc = Status::SetValue; |
| @@ -257,7 +257,7 @@ public: | |||
| 257 | private: | 257 | private: |
| 258 | template <typename Type> | 258 | template <typename Type> |
| 259 | IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) { | 259 | IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) { |
| 260 | for (IR::Block* const imm_pred : block->ImmediatePredecessors()) { | 260 | for (IR::Block* const imm_pred : block->ImmPredecessors()) { |
| 261 | phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred)); | 261 | phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred)); |
| 262 | } | 262 | } |
| 263 | return TryRemoveTrivialPhi(phi, block, UndefOpcode(variable)); | 263 | return TryRemoveTrivialPhi(phi, block, UndefOpcode(variable)); |