diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/function.h | 1 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/post_order.cpp | 48 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/post_order.h | 13 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 12 |
4 files changed, 70 insertions, 4 deletions
diff --git a/src/shader_recompiler/frontend/ir/function.h b/src/shader_recompiler/frontend/ir/function.h index fd7d56419..d1f061146 100644 --- a/src/shader_recompiler/frontend/ir/function.h +++ b/src/shader_recompiler/frontend/ir/function.h | |||
| @@ -12,6 +12,7 @@ namespace Shader::IR { | |||
| 12 | 12 | ||
| 13 | struct Function { | 13 | struct Function { |
| 14 | BlockList blocks; | 14 | BlockList blocks; |
| 15 | BlockList post_order_blocks; | ||
| 15 | }; | 16 | }; |
| 16 | 17 | ||
| 17 | } // namespace Shader::IR | 18 | } // namespace Shader::IR |
diff --git a/src/shader_recompiler/frontend/ir/post_order.cpp b/src/shader_recompiler/frontend/ir/post_order.cpp new file mode 100644 index 000000000..a48b8dec5 --- /dev/null +++ b/src/shader_recompiler/frontend/ir/post_order.cpp | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <boost/container/flat_set.hpp> | ||
| 6 | #include <boost/container/small_vector.hpp> | ||
| 7 | |||
| 8 | #include "shader_recompiler/frontend/ir/basic_block.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/post_order.h" | ||
| 10 | |||
| 11 | namespace Shader::IR { | ||
| 12 | |||
| 13 | BlockList PostOrder(const BlockList& blocks) { | ||
| 14 | boost::container::small_vector<Block*, 16> block_stack; | ||
| 15 | boost::container::flat_set<Block*> visited; | ||
| 16 | |||
| 17 | BlockList post_order_blocks; | ||
| 18 | post_order_blocks.reserve(blocks.size()); | ||
| 19 | |||
| 20 | Block* const first_block{blocks.front()}; | ||
| 21 | visited.insert(first_block); | ||
| 22 | block_stack.push_back(first_block); | ||
| 23 | |||
| 24 | const auto visit_branch = [&](Block* block, Block* branch) { | ||
| 25 | if (!branch) { | ||
| 26 | return false; | ||
| 27 | } | ||
| 28 | if (!visited.insert(branch).second) { | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | // Calling push_back twice is faster than insert on msvc | ||
| 32 | block_stack.push_back(block); | ||
| 33 | block_stack.push_back(branch); | ||
| 34 | return true; | ||
| 35 | }; | ||
| 36 | while (!block_stack.empty()) { | ||
| 37 | Block* const block{block_stack.back()}; | ||
| 38 | block_stack.pop_back(); | ||
| 39 | |||
| 40 | if (!visit_branch(block, block->TrueBranch()) && | ||
| 41 | !visit_branch(block, block->FalseBranch())) { | ||
| 42 | post_order_blocks.push_back(block); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | return post_order_blocks; | ||
| 46 | } | ||
| 47 | |||
| 48 | } // namespace Shader::IR | ||
diff --git a/src/shader_recompiler/frontend/ir/post_order.h b/src/shader_recompiler/frontend/ir/post_order.h new file mode 100644 index 000000000..30137ff57 --- /dev/null +++ b/src/shader_recompiler/frontend/ir/post_order.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "shader_recompiler/frontend/ir/basic_block.h" | ||
| 8 | |||
| 9 | namespace Shader::IR { | ||
| 10 | |||
| 11 | BlockList PostOrder(const BlockList& blocks); | ||
| 12 | |||
| 13 | } // namespace Shader::IR | ||
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index 9fa912ed8..dab6d68c0 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | 8 | ||
| 9 | #include "shader_recompiler/frontend/ir/basic_block.h" | 9 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 10 | #include "shader_recompiler/frontend/ir/post_order.h" | ||
| 10 | #include "shader_recompiler/frontend/ir/structured_control_flow.h" | 11 | #include "shader_recompiler/frontend/ir/structured_control_flow.h" |
| 11 | #include "shader_recompiler/frontend/maxwell/program.h" | 12 | #include "shader_recompiler/frontend/maxwell/program.h" |
| 12 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" | 13 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" |
| @@ -56,11 +57,14 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | fmt::print(stdout, "No optimizations: {}", IR::DumpProgram(program)); | 59 | fmt::print(stdout, "No optimizations: {}", IR::DumpProgram(program)); |
| 59 | std::ranges::for_each(functions, Optimization::SsaRewritePass); | ||
| 60 | for (IR::Function& function : functions) { | 60 | for (IR::Function& function : functions) { |
| 61 | Optimization::Invoke(Optimization::GlobalMemoryToStorageBufferPass, function); | 61 | function.post_order_blocks = PostOrder(function.blocks); |
| 62 | Optimization::Invoke(Optimization::ConstantPropagationPass, function); | 62 | Optimization::SsaRewritePass(function.post_order_blocks); |
| 63 | Optimization::Invoke(Optimization::DeadCodeEliminationPass, function); | 63 | } |
| 64 | for (IR::Function& function : functions) { | ||
| 65 | Optimization::PostOrderInvoke(Optimization::GlobalMemoryToStorageBufferPass, function); | ||
| 66 | Optimization::PostOrderInvoke(Optimization::ConstantPropagationPass, function); | ||
| 67 | Optimization::PostOrderInvoke(Optimization::DeadCodeEliminationPass, function); | ||
| 64 | Optimization::IdentityRemovalPass(function); | 68 | Optimization::IdentityRemovalPass(function); |
| 65 | Optimization::VerificationPass(function); | 69 | Optimization::VerificationPass(function); |
| 66 | } | 70 | } |