diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/program.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 69 |
1 files changed, 35 insertions, 34 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index 8cdd20804..9fa912ed8 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -4,57 +4,58 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <vector> | ||
| 7 | 8 | ||
| 8 | #include "shader_recompiler/frontend/ir/basic_block.h" | 9 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 10 | #include "shader_recompiler/frontend/ir/structured_control_flow.h" | ||
| 9 | #include "shader_recompiler/frontend/maxwell/program.h" | 11 | #include "shader_recompiler/frontend/maxwell/program.h" |
| 10 | #include "shader_recompiler/frontend/maxwell/termination_code.h" | ||
| 11 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" | 12 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" |
| 12 | #include "shader_recompiler/ir_opt/passes.h" | 13 | #include "shader_recompiler/ir_opt/passes.h" |
| 13 | 14 | ||
| 14 | namespace Shader::Maxwell { | 15 | namespace Shader::Maxwell { |
| 15 | namespace { | 16 | namespace { |
| 16 | void TranslateCode(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 17 | IR::BlockList TranslateCode(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, |
| 17 | Environment& env, const Flow::Function& cfg_function, IR::Function& function, | 18 | Environment& env, Flow::Function& cfg_function) { |
| 18 | std::span<IR::Block*> block_map) { | ||
| 19 | const size_t num_blocks{cfg_function.blocks.size()}; | 19 | const size_t num_blocks{cfg_function.blocks.size()}; |
| 20 | function.blocks.reserve(num_blocks); | 20 | std::vector<IR::Block*> blocks(cfg_function.blocks.size()); |
| 21 | 21 | std::ranges::for_each(cfg_function.blocks, [&, i = size_t{0}](auto& cfg_block) mutable { | |
| 22 | for (const Flow::BlockId block_id : cfg_function.blocks) { | 22 | const u32 begin{cfg_block.begin.Offset()}; |
| 23 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; | 23 | const u32 end{cfg_block.end.Offset()}; |
| 24 | 24 | blocks[i] = block_pool.Create(inst_pool, begin, end); | |
| 25 | IR::Block* const ir_block{block_pool.Create(Translate(inst_pool, env, flow_block))}; | 25 | cfg_block.ir = blocks[i]; |
| 26 | block_map[flow_block.id] = ir_block; | 26 | ++i; |
| 27 | function.blocks.emplace_back(ir_block); | 27 | }); |
| 28 | } | 28 | std::ranges::for_each(cfg_function.blocks, [&, i = size_t{0}](auto& cfg_block) mutable { |
| 29 | } | 29 | IR::Block* const block{blocks[i]}; |
| 30 | 30 | ++i; | |
| 31 | void EmitTerminationInsts(const Flow::Function& cfg_function, | 31 | if (cfg_block.end_class != Flow::EndClass::Branch) { |
| 32 | std::span<IR::Block* const> block_map) { | 32 | block->SetReturn(); |
| 33 | for (const Flow::BlockId block_id : cfg_function.blocks) { | 33 | } else if (cfg_block.cond == IR::Condition{true}) { |
| 34 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; | 34 | block->SetBranch(cfg_block.branch_true->ir); |
| 35 | EmitTerminationCode(flow_block, block_map); | 35 | } else if (cfg_block.cond == IR::Condition{false}) { |
| 36 | } | 36 | block->SetBranch(cfg_block.branch_false->ir); |
| 37 | } | 37 | } else { |
| 38 | 38 | block->SetBranches(cfg_block.cond, cfg_block.branch_true->ir, | |
| 39 | void TranslateFunction(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 39 | cfg_block.branch_false->ir); |
| 40 | Environment& env, const Flow::Function& cfg_function, | 40 | } |
| 41 | IR::Function& function) { | 41 | }); |
| 42 | std::vector<IR::Block*> block_map; | 42 | return IR::VisitAST(inst_pool, block_pool, blocks, |
| 43 | block_map.resize(cfg_function.blocks_data.size()); | 43 | [&](IR::Block* block) { Translate(env, block); }); |
| 44 | |||
| 45 | TranslateCode(inst_pool, block_pool, env, cfg_function, function, block_map); | ||
| 46 | EmitTerminationInsts(cfg_function, block_map); | ||
| 47 | } | 44 | } |
| 48 | } // Anonymous namespace | 45 | } // Anonymous namespace |
| 49 | 46 | ||
| 50 | IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 47 | IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, |
| 51 | Environment& env, const Flow::CFG& cfg) { | 48 | Environment& env, Flow::CFG& cfg) { |
| 52 | IR::Program program; | 49 | IR::Program program; |
| 53 | auto& functions{program.functions}; | 50 | auto& functions{program.functions}; |
| 54 | functions.reserve(cfg.Functions().size()); | 51 | functions.reserve(cfg.Functions().size()); |
| 55 | for (const Flow::Function& cfg_function : cfg.Functions()) { | 52 | for (Flow::Function& cfg_function : cfg.Functions()) { |
| 56 | TranslateFunction(inst_pool, block_pool, env, cfg_function, functions.emplace_back()); | 53 | functions.push_back(IR::Function{ |
| 54 | .blocks{TranslateCode(inst_pool, block_pool, env, cfg_function)}, | ||
| 55 | }); | ||
| 57 | } | 56 | } |
| 57 | |||
| 58 | fmt::print(stdout, "No optimizations: {}", IR::DumpProgram(program)); | ||
| 58 | std::ranges::for_each(functions, Optimization::SsaRewritePass); | 59 | std::ranges::for_each(functions, Optimization::SsaRewritePass); |
| 59 | for (IR::Function& function : functions) { | 60 | for (IR::Function& function : functions) { |
| 60 | Optimization::Invoke(Optimization::GlobalMemoryToStorageBufferPass, function); | 61 | Optimization::Invoke(Optimization::GlobalMemoryToStorageBufferPass, function); |