summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/CMakeLists.txt2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h12
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp10
-rw-r--r--src/shader_recompiler/frontend/ir/function.h1
-rw-r--r--src/shader_recompiler/frontend/ir/post_order.cpp48
-rw-r--r--src/shader_recompiler/frontend/ir/post_order.h13
-rw-r--r--src/shader_recompiler/frontend/maxwell/program.cpp12
-rw-r--r--src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp2
-rw-r--r--src/shader_recompiler/ir_opt/passes.h8
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp62
-rw-r--r--src/shader_recompiler/main.cpp18
12 files changed, 150 insertions, 46 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 27fc79e21..e1f4276a1 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -32,6 +32,8 @@ add_executable(shader_recompiler
32 frontend/ir/opcodes.cpp 32 frontend/ir/opcodes.cpp
33 frontend/ir/opcodes.h 33 frontend/ir/opcodes.h
34 frontend/ir/opcodes.inc 34 frontend/ir/opcodes.inc
35 frontend/ir/post_order.cpp
36 frontend/ir/post_order.h
35 frontend/ir/pred.h 37 frontend/ir/pred.h
36 frontend/ir/program.cpp 38 frontend/ir/program.cpp
37 frontend/ir/program.h 39 frontend/ir/program.h
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 46ec7a1bb..6b09757d1 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -159,10 +159,10 @@ private:
159 Id EmitWorkgroupId(EmitContext& ctx); 159 Id EmitWorkgroupId(EmitContext& ctx);
160 Id EmitLocalInvocationId(EmitContext& ctx); 160 Id EmitLocalInvocationId(EmitContext& ctx);
161 Id EmitUndefU1(EmitContext& ctx); 161 Id EmitUndefU1(EmitContext& ctx);
162 void EmitUndefU8(EmitContext& ctx); 162 Id EmitUndefU8(EmitContext& ctx);
163 void EmitUndefU16(EmitContext& ctx); 163 Id EmitUndefU16(EmitContext& ctx);
164 void EmitUndefU32(EmitContext& ctx); 164 Id EmitUndefU32(EmitContext& ctx);
165 void EmitUndefU64(EmitContext& ctx); 165 Id EmitUndefU64(EmitContext& ctx);
166 void EmitLoadGlobalU8(EmitContext& ctx); 166 void EmitLoadGlobalU8(EmitContext& ctx);
167 void EmitLoadGlobalS8(EmitContext& ctx); 167 void EmitLoadGlobalS8(EmitContext& ctx);
168 void EmitLoadGlobalU16(EmitContext& ctx); 168 void EmitLoadGlobalU16(EmitContext& ctx);
@@ -297,12 +297,12 @@ private:
297 void EmitBitFieldInsert(EmitContext& ctx); 297 void EmitBitFieldInsert(EmitContext& ctx);
298 void EmitBitFieldSExtract(EmitContext& ctx); 298 void EmitBitFieldSExtract(EmitContext& ctx);
299 Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); 299 Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count);
300 void EmitSLessThan(EmitContext& ctx); 300 Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs);
301 void EmitULessThan(EmitContext& ctx); 301 void EmitULessThan(EmitContext& ctx);
302 void EmitIEqual(EmitContext& ctx); 302 void EmitIEqual(EmitContext& ctx);
303 void EmitSLessThanEqual(EmitContext& ctx); 303 void EmitSLessThanEqual(EmitContext& ctx);
304 void EmitULessThanEqual(EmitContext& ctx); 304 void EmitULessThanEqual(EmitContext& ctx);
305 void EmitSGreaterThan(EmitContext& ctx); 305 Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs);
306 void EmitUGreaterThan(EmitContext& ctx); 306 void EmitUGreaterThan(EmitContext& ctx);
307 void EmitINotEqual(EmitContext& ctx); 307 void EmitINotEqual(EmitContext& ctx);
308 void EmitSGreaterThanEqual(EmitContext& ctx); 308 void EmitSGreaterThanEqual(EmitContext& ctx);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index 3ef4f3d78..e811a63ab 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -73,8 +73,8 @@ Id EmitSPIRV::EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id coun
73 return ctx.OpBitFieldUExtract(ctx.u32[1], base, offset, count); 73 return ctx.OpBitFieldUExtract(ctx.u32[1], base, offset, count);
74} 74}
75 75
76void EmitSPIRV::EmitSLessThan(EmitContext&) { 76Id EmitSPIRV::EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) {
77 throw NotImplementedException("SPIR-V Instruction"); 77 return ctx.OpSLessThan(ctx.u1, lhs, rhs);
78} 78}
79 79
80void EmitSPIRV::EmitULessThan(EmitContext&) { 80void EmitSPIRV::EmitULessThan(EmitContext&) {
@@ -93,8 +93,8 @@ void EmitSPIRV::EmitULessThanEqual(EmitContext&) {
93 throw NotImplementedException("SPIR-V Instruction"); 93 throw NotImplementedException("SPIR-V Instruction");
94} 94}
95 95
96void EmitSPIRV::EmitSGreaterThan(EmitContext&) { 96Id EmitSPIRV::EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
97 throw NotImplementedException("SPIR-V Instruction"); 97 return ctx.OpSGreaterThan(ctx.u1, lhs, rhs);
98} 98}
99 99
100void EmitSPIRV::EmitUGreaterThan(EmitContext&) { 100void EmitSPIRV::EmitUGreaterThan(EmitContext&) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp
index 859b60a95..a6f542360 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp
@@ -10,19 +10,19 @@ Id EmitSPIRV::EmitUndefU1(EmitContext& ctx) {
10 return ctx.OpUndef(ctx.u1); 10 return ctx.OpUndef(ctx.u1);
11} 11}
12 12
13void EmitSPIRV::EmitUndefU8(EmitContext&) { 13Id EmitSPIRV::EmitUndefU8(EmitContext&) {
14 throw NotImplementedException("SPIR-V Instruction"); 14 throw NotImplementedException("SPIR-V Instruction");
15} 15}
16 16
17void EmitSPIRV::EmitUndefU16(EmitContext&) { 17Id EmitSPIRV::EmitUndefU16(EmitContext&) {
18 throw NotImplementedException("SPIR-V Instruction"); 18 throw NotImplementedException("SPIR-V Instruction");
19} 19}
20 20
21void EmitSPIRV::EmitUndefU32(EmitContext&) { 21Id EmitSPIRV::EmitUndefU32(EmitContext& ctx) {
22 throw NotImplementedException("SPIR-V Instruction"); 22 return ctx.OpUndef(ctx.u32[1]);
23} 23}
24 24
25void EmitSPIRV::EmitUndefU64(EmitContext&) { 25Id EmitSPIRV::EmitUndefU64(EmitContext&) {
26 throw NotImplementedException("SPIR-V Instruction"); 26 throw NotImplementedException("SPIR-V Instruction");
27} 27}
28 28
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
13struct Function { 13struct 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
11namespace Shader::IR {
12
13BlockList 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
9namespace Shader::IR {
10
11BlockList 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 }
diff --git a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
index bbaa412f6..132b2012a 100644
--- a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
+++ b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
@@ -13,7 +13,7 @@ namespace Shader::Optimization {
13void DeadCodeEliminationPass(IR::Block& block) { 13void DeadCodeEliminationPass(IR::Block& block) {
14 // We iterate over the instructions in reverse order. 14 // We iterate over the instructions in reverse order.
15 // This is because removing an instruction reduces the number of uses for earlier instructions. 15 // This is because removing an instruction reduces the number of uses for earlier instructions.
16 for (IR::Inst& inst : std::views::reverse(block)) { 16 for (IR::Inst& inst : block | std::views::reverse) {
17 if (!inst.HasUses() && !inst.MayHaveSideEffects()) { 17 if (!inst.HasUses() && !inst.MayHaveSideEffects()) {
18 inst.Invalidate(); 18 inst.Invalidate();
19 } 19 }
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h
index 578a24d89..30eb31588 100644
--- a/src/shader_recompiler/ir_opt/passes.h
+++ b/src/shader_recompiler/ir_opt/passes.h
@@ -4,14 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <span>
8
7#include "shader_recompiler/frontend/ir/basic_block.h" 9#include "shader_recompiler/frontend/ir/basic_block.h"
8#include "shader_recompiler/frontend/ir/function.h" 10#include "shader_recompiler/frontend/ir/function.h"
9 11
10namespace Shader::Optimization { 12namespace Shader::Optimization {
11 13
12template <typename Func> 14template <typename Func>
13void Invoke(Func&& func, IR::Function& function) { 15void PostOrderInvoke(Func&& func, IR::Function& function) {
14 for (const auto& block : function.blocks) { 16 for (const auto& block : function.post_order_blocks) {
15 func(*block); 17 func(*block);
16 } 18 }
17} 19}
@@ -20,7 +22,7 @@ void ConstantPropagationPass(IR::Block& block);
20void DeadCodeEliminationPass(IR::Block& block); 22void DeadCodeEliminationPass(IR::Block& block);
21void GlobalMemoryToStorageBufferPass(IR::Block& block); 23void GlobalMemoryToStorageBufferPass(IR::Block& block);
22void IdentityRemovalPass(IR::Function& function); 24void IdentityRemovalPass(IR::Function& function);
23void SsaRewritePass(IR::Function& function); 25void SsaRewritePass(std::span<IR::Block* const> post_order_blocks);
24void VerificationPass(const IR::Function& function); 26void VerificationPass(const IR::Function& function);
25 27
26} // namespace Shader::Optimization 28} // namespace Shader::Optimization
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index 7eaf719c4..13f9c914a 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -14,7 +14,13 @@
14// https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6 14// https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6
15// 15//
16 16
17#include <ranges>
18#include <span>
19#include <variant>
20#include <vector>
21
17#include <boost/container/flat_map.hpp> 22#include <boost/container/flat_map.hpp>
23#include <boost/container/flat_set.hpp>
18 24
19#include "shader_recompiler/frontend/ir/basic_block.h" 25#include "shader_recompiler/frontend/ir/basic_block.h"
20#include "shader_recompiler/frontend/ir/function.h" 26#include "shader_recompiler/frontend/ir/function.h"
@@ -26,9 +32,9 @@
26 32
27namespace Shader::Optimization { 33namespace Shader::Optimization {
28namespace { 34namespace {
29using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; 35struct FlagTag {
30 36 auto operator<=>(const FlagTag&) const noexcept = default;
31struct FlagTag {}; 37};
32struct ZeroFlagTag : FlagTag {}; 38struct ZeroFlagTag : FlagTag {};
33struct SignFlagTag : FlagTag {}; 39struct SignFlagTag : FlagTag {};
34struct CarryFlagTag : FlagTag {}; 40struct CarryFlagTag : FlagTag {};
@@ -38,9 +44,15 @@ struct GotoVariable : FlagTag {
38 GotoVariable() = default; 44 GotoVariable() = default;
39 explicit GotoVariable(u32 index_) : index{index_} {} 45 explicit GotoVariable(u32 index_) : index{index_} {}
40 46
47 auto operator<=>(const GotoVariable&) const noexcept = default;
48
41 u32 index; 49 u32 index;
42}; 50};
43 51
52using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
53 OverflowFlagTag, GotoVariable>;
54using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
55
44struct DefTable { 56struct DefTable {
45 [[nodiscard]] ValueMap& operator[](IR::Reg variable) noexcept { 57 [[nodiscard]] ValueMap& operator[](IR::Reg variable) noexcept {
46 return regs[IR::RegIndex(variable)]; 58 return regs[IR::RegIndex(variable)];
@@ -102,19 +114,35 @@ public:
102 } 114 }
103 115
104 IR::Value ReadVariable(auto variable, IR::Block* block) { 116 IR::Value ReadVariable(auto variable, IR::Block* block) {
105 auto& def{current_def[variable]}; 117 const ValueMap& def{current_def[variable]};
106 if (const auto it{def.find(block)}; it != def.end()) { 118 if (const auto it{def.find(block)}; it != def.end()) {
107 return it->second; 119 return it->second;
108 } 120 }
109 return ReadVariableRecursive(variable, block); 121 return ReadVariableRecursive(variable, block);
110 } 122 }
111 123
124 void SealBlock(IR::Block* block) {
125 const auto it{incomplete_phis.find(block)};
126 if (it != incomplete_phis.end()) {
127 for (auto& [variant, phi] : it->second) {
128 std::visit([&](auto& variable) { AddPhiOperands(variable, *phi, block); }, variant);
129 }
130 }
131 sealed_blocks.insert(block);
132 }
133
112private: 134private:
113 IR::Value ReadVariableRecursive(auto variable, IR::Block* block) { 135 IR::Value ReadVariableRecursive(auto variable, IR::Block* block) {
114 IR::Value val; 136 IR::Value val;
115 if (const std::span preds{block->ImmediatePredecessors()}; preds.size() == 1) { 137 if (!sealed_blocks.contains(block)) {
138 // Incomplete CFG
139 IR::Inst* phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)};
140 incomplete_phis[block].insert_or_assign(variable, phi);
141 val = IR::Value{&*phi};
142 } else if (const std::span imm_preds{block->ImmediatePredecessors()};
143 imm_preds.size() == 1) {
116 // Optimize the common case of one predecessor: no phi needed 144 // Optimize the common case of one predecessor: no phi needed
117 val = ReadVariable(variable, preds.front()); 145 val = ReadVariable(variable, imm_preds.front());
118 } else { 146 } else {
119 // Break potential cycles with operandless phi 147 // Break potential cycles with operandless phi
120 IR::Inst& phi_inst{*block->PrependNewInst(block->begin(), IR::Opcode::Phi)}; 148 IR::Inst& phi_inst{*block->PrependNewInst(block->begin(), IR::Opcode::Phi)};
@@ -127,8 +155,8 @@ private:
127 } 155 }
128 156
129 IR::Value AddPhiOperands(auto variable, IR::Inst& phi, IR::Block* block) { 157 IR::Value AddPhiOperands(auto variable, IR::Inst& phi, IR::Block* block) {
130 for (IR::Block* const pred : block->ImmediatePredecessors()) { 158 for (IR::Block* const imm_pred : block->ImmediatePredecessors()) {
131 phi.AddPhiOperand(pred, ReadVariable(variable, pred)); 159 phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred));
132 } 160 }
133 return TryRemoveTrivialPhi(phi, block, UndefOpcode(variable)); 161 return TryRemoveTrivialPhi(phi, block, UndefOpcode(variable));
134 } 162 }
@@ -159,6 +187,9 @@ private:
159 return same; 187 return same;
160 } 188 }
161 189
190 boost::container::flat_set<IR::Block*> sealed_blocks;
191 boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>>
192 incomplete_phis;
162 DefTable current_def; 193 DefTable current_def;
163}; 194};
164 195
@@ -218,14 +249,19 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
218 break; 249 break;
219 } 250 }
220} 251}
252
253void VisitBlock(Pass& pass, IR::Block* block) {
254 for (IR::Inst& inst : block->Instructions()) {
255 VisitInst(pass, block, inst);
256 }
257 pass.SealBlock(block);
258}
221} // Anonymous namespace 259} // Anonymous namespace
222 260
223void SsaRewritePass(IR::Function& function) { 261void SsaRewritePass(std::span<IR::Block* const> post_order_blocks) {
224 Pass pass; 262 Pass pass;
225 for (IR::Block* const block : function.blocks) { 263 for (IR::Block* const block : post_order_blocks | std::views::reverse) {
226 for (IR::Inst& inst : block->Instructions()) { 264 VisitBlock(pass, block);
227 VisitInst(pass, block, inst);
228 }
229 } 265 }
230} 266}
231 267
diff --git a/src/shader_recompiler/main.cpp b/src/shader_recompiler/main.cpp
index 92358232c..29f65966c 100644
--- a/src/shader_recompiler/main.cpp
+++ b/src/shader_recompiler/main.cpp
@@ -69,14 +69,12 @@ int main() {
69 69
70 // FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS8F146B41DB6BD826.bin"}; 70 // FileEnvironment env{"D:\\Shaders\\Database\\Oninaki\\CS8F146B41DB6BD826.bin"};
71 FileEnvironment env{"D:\\Shaders\\shader.bin"}; 71 FileEnvironment env{"D:\\Shaders\\shader.bin"};
72 for (int i = 0; i < 1; ++i) { 72 block_pool->ReleaseContents();
73 block_pool->ReleaseContents(); 73 inst_pool->ReleaseContents();
74 inst_pool->ReleaseContents(); 74 flow_block_pool->ReleaseContents();
75 flow_block_pool->ReleaseContents(); 75 Flow::CFG cfg{env, *flow_block_pool, 0};
76 Flow::CFG cfg{env, *flow_block_pool, 0}; 76 fmt::print(stdout, "{}\n", cfg.Dot());
77 fmt::print(stdout, "{}\n", cfg.Dot()); 77 IR::Program program{TranslateProgram(*inst_pool, *block_pool, env, cfg)};
78 IR::Program program{TranslateProgram(*inst_pool, *block_pool, env, cfg)}; 78 fmt::print(stdout, "{}\n", IR::DumpProgram(program));
79 fmt::print(stdout, "{}\n", IR::DumpProgram(program)); 79 // Backend::SPIRV::EmitSPIRV spirv{program};
80 Backend::SPIRV::EmitSPIRV spirv{program};
81 }
82} 80}