diff options
| author | 2021-03-14 03:41:05 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 71f96fa6366dc6dd306a953bca1b958fb32bc55a (patch) | |
| tree | 12e13f9502e4b9510446c967a831e5d4bacb729e /src/shader_recompiler/frontend/maxwell/program.cpp | |
| parent | spirv: Add SignedZeroInfNanPreserve logic (diff) | |
| download | yuzu-71f96fa6366dc6dd306a953bca1b958fb32bc55a.tar.gz yuzu-71f96fa6366dc6dd306a953bca1b958fb32bc55a.tar.xz yuzu-71f96fa6366dc6dd306a953bca1b958fb32bc55a.zip | |
shader: Implement CAL inlining function calls
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/program.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 71 |
1 files changed, 24 insertions, 47 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index b270bbccd..8bfa64326 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -8,67 +8,44 @@ | |||
| 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/post_order.h" |
| 11 | #include "shader_recompiler/frontend/ir/structured_control_flow.h" | ||
| 12 | #include "shader_recompiler/frontend/maxwell/program.h" | 11 | #include "shader_recompiler/frontend/maxwell/program.h" |
| 12 | #include "shader_recompiler/frontend/maxwell/structured_control_flow.h" | ||
| 13 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" | 13 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" |
| 14 | #include "shader_recompiler/ir_opt/passes.h" | 14 | #include "shader_recompiler/ir_opt/passes.h" |
| 15 | 15 | ||
| 16 | namespace Shader::Maxwell { | 16 | namespace Shader::Maxwell { |
| 17 | namespace { | 17 | |
| 18 | IR::BlockList TranslateCode(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 18 | static void RemoveUnreachableBlocks(IR::Program& program) { |
| 19 | Environment& env, Flow::Function& cfg_function) { | 19 | // Some blocks might be unreachable if a function call exists unconditionally |
| 20 | const size_t num_blocks{cfg_function.blocks.size()}; | 20 | // If this happens the number of blocks and post order blocks will mismatch |
| 21 | std::vector<IR::Block*> blocks(cfg_function.blocks.size()); | 21 | if (program.blocks.size() == program.post_order_blocks.size()) { |
| 22 | std::ranges::for_each(cfg_function.blocks, [&, i = size_t{0}](auto& cfg_block) mutable { | 22 | return; |
| 23 | const u32 begin{cfg_block.begin.Offset()}; | 23 | } |
| 24 | const u32 end{cfg_block.end.Offset()}; | 24 | const IR::BlockList& post_order{program.post_order_blocks}; |
| 25 | blocks[i] = block_pool.Create(inst_pool, begin, end); | 25 | std::erase_if(program.blocks, [&](IR::Block* block) { |
| 26 | cfg_block.ir = blocks[i]; | 26 | return std::ranges::find(post_order, block) == post_order.end(); |
| 27 | ++i; | ||
| 28 | }); | ||
| 29 | std::ranges::for_each(cfg_function.blocks, [&, i = size_t{0}](auto& cfg_block) mutable { | ||
| 30 | IR::Block* const block{blocks[i]}; | ||
| 31 | ++i; | ||
| 32 | if (cfg_block.end_class != Flow::EndClass::Branch) { | ||
| 33 | block->SetReturn(); | ||
| 34 | } else if (cfg_block.cond == IR::Condition{true}) { | ||
| 35 | block->SetBranch(cfg_block.branch_true->ir); | ||
| 36 | } else if (cfg_block.cond == IR::Condition{false}) { | ||
| 37 | block->SetBranch(cfg_block.branch_false->ir); | ||
| 38 | } else { | ||
| 39 | block->SetBranches(cfg_block.cond, cfg_block.branch_true->ir, | ||
| 40 | cfg_block.branch_false->ir); | ||
| 41 | } | ||
| 42 | }); | 27 | }); |
| 43 | return IR::VisitAST(inst_pool, block_pool, blocks, | ||
| 44 | [&](IR::Block* block) { Translate(env, block); }); | ||
| 45 | } | 28 | } |
| 46 | } // Anonymous namespace | ||
| 47 | 29 | ||
| 48 | IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 30 | IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, |
| 49 | Environment& env, Flow::CFG& cfg) { | 31 | Environment& env, Flow::CFG& cfg) { |
| 50 | IR::Program program; | 32 | IR::Program program; |
| 51 | auto& functions{program.functions}; | 33 | program.blocks = VisitAST(inst_pool, block_pool, env, cfg); |
| 52 | functions.reserve(cfg.Functions().size()); | 34 | program.post_order_blocks = PostOrder(program.blocks); |
| 53 | for (Flow::Function& cfg_function : cfg.Functions()) { | 35 | RemoveUnreachableBlocks(program); |
| 54 | functions.push_back(IR::Function{ | 36 | |
| 55 | .blocks{TranslateCode(inst_pool, block_pool, env, cfg_function)}, | 37 | // Replace instructions before the SSA rewrite |
| 56 | .post_order_blocks{}, | ||
| 57 | }); | ||
| 58 | } | ||
| 59 | Optimization::LowerFp16ToFp32(program); | 38 | Optimization::LowerFp16ToFp32(program); |
| 60 | for (IR::Function& function : functions) { | 39 | |
| 61 | function.post_order_blocks = PostOrder(function.blocks); | 40 | Optimization::SsaRewritePass(program); |
| 62 | Optimization::SsaRewritePass(function.post_order_blocks); | 41 | |
| 63 | } | ||
| 64 | Optimization::GlobalMemoryToStorageBufferPass(program); | 42 | Optimization::GlobalMemoryToStorageBufferPass(program); |
| 65 | Optimization::TexturePass(env, program); | 43 | Optimization::TexturePass(env, program); |
| 66 | for (IR::Function& function : functions) { | 44 | |
| 67 | Optimization::PostOrderInvoke(Optimization::ConstantPropagationPass, function); | 45 | Optimization::ConstantPropagationPass(program); |
| 68 | Optimization::PostOrderInvoke(Optimization::DeadCodeEliminationPass, function); | 46 | Optimization::DeadCodeEliminationPass(program); |
| 69 | Optimization::IdentityRemovalPass(function); | 47 | Optimization::IdentityRemovalPass(program); |
| 70 | Optimization::VerificationPass(function); | 48 | Optimization::VerificationPass(program); |
| 71 | } | ||
| 72 | Optimization::CollectShaderInfoPass(program); | 49 | Optimization::CollectShaderInfoPass(program); |
| 73 | return program; | 50 | return program; |
| 74 | } | 51 | } |