diff options
Diffstat (limited to 'src/shader_recompiler/ir_opt')
| -rw-r--r-- | src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp | 44 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/passes.h | 1 |
2 files changed, 45 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp b/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp new file mode 100644 index 000000000..c3ed27f4f --- /dev/null +++ b/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "shader_recompiler/frontend/ir/program.h" | ||
| 5 | #include "shader_recompiler/ir_opt/passes.h" | ||
| 6 | |||
| 7 | namespace Shader::Optimization { | ||
| 8 | |||
| 9 | void ConditionalBarrierPass(IR::Program& program) { | ||
| 10 | s32 conditional_control_flow_count{0}; | ||
| 11 | s32 conditional_return_count{0}; | ||
| 12 | for (IR::AbstractSyntaxNode& node : program.syntax_list) { | ||
| 13 | switch (node.type) { | ||
| 14 | case IR::AbstractSyntaxNode::Type::If: | ||
| 15 | case IR::AbstractSyntaxNode::Type::Loop: | ||
| 16 | conditional_control_flow_count++; | ||
| 17 | break; | ||
| 18 | case IR::AbstractSyntaxNode::Type::EndIf: | ||
| 19 | case IR::AbstractSyntaxNode::Type::Repeat: | ||
| 20 | conditional_control_flow_count--; | ||
| 21 | break; | ||
| 22 | case IR::AbstractSyntaxNode::Type::Unreachable: | ||
| 23 | case IR::AbstractSyntaxNode::Type::Return: | ||
| 24 | if (conditional_control_flow_count > 0) { | ||
| 25 | conditional_return_count++; | ||
| 26 | } | ||
| 27 | break; | ||
| 28 | case IR::AbstractSyntaxNode::Type::Block: | ||
| 29 | for (IR::Inst& inst : node.data.block->Instructions()) { | ||
| 30 | if ((conditional_control_flow_count > 0 || conditional_return_count > 0) && | ||
| 31 | inst.GetOpcode() == IR::Opcode::Barrier) { | ||
| 32 | LOG_WARNING(Shader, "Barrier within conditional control flow"); | ||
| 33 | inst.ReplaceOpcode(IR::Opcode::Identity); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | break; | ||
| 37 | default: | ||
| 38 | break; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | ASSERT(conditional_control_flow_count == 0); | ||
| 42 | } | ||
| 43 | |||
| 44 | } // namespace Shader::Optimization | ||
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h index 1f8f2ba95..a677bfc65 100644 --- a/src/shader_recompiler/ir_opt/passes.h +++ b/src/shader_recompiler/ir_opt/passes.h | |||
| @@ -13,6 +13,7 @@ struct HostTranslateInfo; | |||
| 13 | namespace Shader::Optimization { | 13 | namespace Shader::Optimization { |
| 14 | 14 | ||
| 15 | void CollectShaderInfoPass(Environment& env, IR::Program& program); | 15 | void CollectShaderInfoPass(Environment& env, IR::Program& program); |
| 16 | void ConditionalBarrierPass(IR::Program& program); | ||
| 16 | void ConstantPropagationPass(Environment& env, IR::Program& program); | 17 | void ConstantPropagationPass(Environment& env, IR::Program& program); |
| 17 | void DeadCodeEliminationPass(IR::Program& program); | 18 | void DeadCodeEliminationPass(IR::Program& program); |
| 18 | void GlobalMemoryToStorageBufferPass(IR::Program& program); | 19 | void GlobalMemoryToStorageBufferPass(IR::Program& program); |