summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/program.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/program.cpp')
-rw-r--r--src/shader_recompiler/frontend/maxwell/program.cpp69
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
14namespace Shader::Maxwell { 15namespace Shader::Maxwell {
15namespace { 16namespace {
16void TranslateCode(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, 17IR::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;
31void 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,
39void 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
50IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, 47IR::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);