diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 75 |
1 files changed, 44 insertions, 31 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index 67a98ba57..49d1f4bfb 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -8,40 +8,53 @@ | |||
| 8 | #include "shader_recompiler/frontend/maxwell/program.h" | 8 | #include "shader_recompiler/frontend/maxwell/program.h" |
| 9 | #include "shader_recompiler/frontend/maxwell/termination_code.h" | 9 | #include "shader_recompiler/frontend/maxwell/termination_code.h" |
| 10 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" | 10 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" |
| 11 | #include "shader_recompiler/ir_opt/passes.h" | ||
| 11 | 12 | ||
| 12 | namespace Shader::Maxwell { | 13 | namespace Shader::Maxwell { |
| 14 | namespace { | ||
| 15 | void TranslateCode(Environment& env, const Flow::Function& cfg_function, IR::Function& function, | ||
| 16 | std::span<IR::Block*> block_map, IR::Block* block_memory) { | ||
| 17 | const size_t num_blocks{cfg_function.blocks.size()}; | ||
| 18 | function.blocks.reserve(num_blocks); | ||
| 13 | 19 | ||
| 14 | Program::Function::~Function() { | 20 | for (const Flow::BlockId block_id : cfg_function.blocks) { |
| 15 | std::ranges::for_each(blocks, &std::destroy_at<IR::Block>); | 21 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; |
| 16 | } | ||
| 17 | |||
| 18 | Program::Program(Environment& env, const Flow::CFG& cfg) { | ||
| 19 | std::vector<IR::Block*> block_map; | ||
| 20 | functions.reserve(cfg.Functions().size()); | ||
| 21 | 22 | ||
| 22 | for (const Flow::Function& cfg_function : cfg.Functions()) { | 23 | function.blocks.emplace_back(std::construct_at(block_memory, Translate(env, flow_block))); |
| 23 | Function& function{functions.emplace_back()}; | 24 | block_map[flow_block.id] = function.blocks.back().get(); |
| 25 | ++block_memory; | ||
| 26 | } | ||
| 27 | } | ||
| 24 | 28 | ||
| 25 | const size_t num_blocks{cfg_function.blocks.size()}; | 29 | void EmitTerminationInsts(const Flow::Function& cfg_function, |
| 26 | IR::Block* block_memory{block_alloc_pool.allocate(num_blocks)}; | 30 | std::span<IR::Block* const> block_map) { |
| 27 | function.blocks.reserve(num_blocks); | 31 | for (const Flow::BlockId block_id : cfg_function.blocks) { |
| 32 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; | ||
| 33 | EmitTerminationCode(flow_block, block_map); | ||
| 34 | } | ||
| 35 | } | ||
| 28 | 36 | ||
| 29 | block_map.resize(cfg_function.blocks_data.size()); | 37 | void TranslateFunction(Environment& env, const Flow::Function& cfg_function, IR::Function& function, |
| 38 | IR::Block* block_memory) { | ||
| 39 | std::vector<IR::Block*> block_map; | ||
| 40 | block_map.resize(cfg_function.blocks_data.size()); | ||
| 30 | 41 | ||
| 31 | // Visit the instructions of all blocks | 42 | TranslateCode(env, cfg_function, function, block_map, block_memory); |
| 32 | for (const Flow::BlockId block_id : cfg_function.blocks) { | 43 | EmitTerminationInsts(cfg_function, block_map); |
| 33 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; | 44 | } |
| 45 | } // Anonymous namespace | ||
| 34 | 46 | ||
| 35 | IR::Block* const block{std::construct_at(block_memory, Translate(env, flow_block))}; | 47 | Program::Program(Environment& env, const Flow::CFG& cfg) { |
| 36 | ++block_memory; | 48 | functions.reserve(cfg.Functions().size()); |
| 37 | function.blocks.push_back(block); | 49 | for (const Flow::Function& cfg_function : cfg.Functions()) { |
| 38 | block_map[flow_block.id] = block; | 50 | TranslateFunction(env, cfg_function, functions.emplace_back(), |
| 39 | } | 51 | block_alloc_pool.allocate(cfg_function.blocks.size())); |
| 40 | // Now that all blocks are defined, emit the termination instructions | 52 | } |
| 41 | for (const Flow::BlockId block_id : cfg_function.blocks) { | 53 | std::ranges::for_each(functions, Optimization::SsaRewritePass); |
| 42 | const Flow::Block& flow_block{cfg_function.blocks_data[block_id]}; | 54 | for (IR::Function& function : functions) { |
| 43 | EmitTerminationCode(flow_block, block_map); | 55 | Optimization::Invoke(Optimization::DeadCodeEliminationPass, function); |
| 44 | } | 56 | Optimization::Invoke(Optimization::IdentityRemovalPass, function); |
| 57 | // Optimization::Invoke(Optimization::VerificationPass, function); | ||
| 45 | } | 58 | } |
| 46 | } | 59 | } |
| 47 | 60 | ||
| @@ -50,16 +63,16 @@ std::string DumpProgram(const Program& program) { | |||
| 50 | std::map<const IR::Inst*, size_t> inst_to_index; | 63 | std::map<const IR::Inst*, size_t> inst_to_index; |
| 51 | std::map<const IR::Block*, size_t> block_to_index; | 64 | std::map<const IR::Block*, size_t> block_to_index; |
| 52 | 65 | ||
| 53 | for (const Program::Function& function : program.functions) { | 66 | for (const IR::Function& function : program.functions) { |
| 54 | for (const IR::Block* const block : function.blocks) { | 67 | for (const auto& block : function.blocks) { |
| 55 | block_to_index.emplace(block, index); | 68 | block_to_index.emplace(block.get(), index); |
| 56 | ++index; | 69 | ++index; |
| 57 | } | 70 | } |
| 58 | } | 71 | } |
| 59 | std::string ret; | 72 | std::string ret; |
| 60 | for (const Program::Function& function : program.functions) { | 73 | for (const IR::Function& function : program.functions) { |
| 61 | ret += fmt::format("Function\n"); | 74 | ret += fmt::format("Function\n"); |
| 62 | for (const IR::Block* const block : function.blocks) { | 75 | for (const auto& block : function.blocks) { |
| 63 | ret += IR::DumpBlock(*block, block_to_index, inst_to_index, index) + '\n'; | 76 | ret += IR::DumpBlock(*block, block_to_index, inst_to_index, index) + '\n'; |
| 64 | } | 77 | } |
| 65 | } | 78 | } |