diff options
Diffstat (limited to 'src/shader_recompiler/ir_opt')
10 files changed, 44 insertions, 57 deletions
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 70d75ad6c..708b6b267 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -296,11 +296,9 @@ void Visit(Info& info, IR::Inst& inst) { | |||
| 296 | 296 | ||
| 297 | void CollectShaderInfoPass(IR::Program& program) { | 297 | void CollectShaderInfoPass(IR::Program& program) { |
| 298 | Info& info{program.info}; | 298 | Info& info{program.info}; |
| 299 | for (IR::Function& function : program.functions) { | 299 | for (IR::Block* const block : program.post_order_blocks) { |
| 300 | for (IR::Block* const block : function.post_order_blocks) { | 300 | for (IR::Inst& inst : block->Instructions()) { |
| 301 | for (IR::Inst& inst : block->Instructions()) { | 301 | Visit(info, inst); |
| 302 | Visit(info, inst); | ||
| 303 | } | ||
| 304 | } | 302 | } |
| 305 | } | 303 | } |
| 306 | } | 304 | } |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index 7ba9ebe9b..a39db2bf1 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -371,9 +371,11 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 371 | } | 371 | } |
| 372 | } // Anonymous namespace | 372 | } // Anonymous namespace |
| 373 | 373 | ||
| 374 | void ConstantPropagationPass(IR::Block& block) { | 374 | void ConstantPropagationPass(IR::Program& program) { |
| 375 | for (IR::Inst& inst : block) { | 375 | for (IR::Block* const block : program.post_order_blocks) { |
| 376 | ConstantPropagation(block, inst); | 376 | for (IR::Inst& inst : block->Instructions()) { |
| 377 | ConstantPropagation(*block, inst); | ||
| 378 | } | ||
| 377 | } | 379 | } |
| 378 | } | 380 | } |
| 379 | 381 | ||
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 132b2012a..8ad59f42e 100644 --- a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp +++ b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp | |||
| @@ -10,12 +10,14 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Optimization { | 11 | namespace Shader::Optimization { |
| 12 | 12 | ||
| 13 | void DeadCodeEliminationPass(IR::Block& block) { | 13 | void DeadCodeEliminationPass(IR::Program& program) { |
| 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 : block | std::views::reverse) { | 16 | for (IR::Block* const block : program.post_order_blocks) { |
| 17 | if (!inst.HasUses() && !inst.MayHaveSideEffects()) { | 17 | for (IR::Inst& inst : block->Instructions() | std::views::reverse) { |
| 18 | inst.Invalidate(); | 18 | if (!inst.HasUses() && !inst.MayHaveSideEffects()) { |
| 19 | inst.Invalidate(); | ||
| 20 | } | ||
| 19 | } | 21 | } |
| 20 | } | 22 | } |
| 21 | } | 23 | } |
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp index 5d98d278e..1faa1ec88 100644 --- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp +++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp | |||
| @@ -351,14 +351,12 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) { | |||
| 351 | StorageBufferSet storage_buffers; | 351 | StorageBufferSet storage_buffers; |
| 352 | StorageInstVector to_replace; | 352 | StorageInstVector to_replace; |
| 353 | 353 | ||
| 354 | for (IR::Function& function : program.functions) { | 354 | for (IR::Block* const block : program.post_order_blocks) { |
| 355 | for (IR::Block* const block : function.post_order_blocks) { | 355 | for (IR::Inst& inst : block->Instructions()) { |
| 356 | for (IR::Inst& inst : block->Instructions()) { | 356 | if (!IsGlobalMemory(inst)) { |
| 357 | if (!IsGlobalMemory(inst)) { | 357 | continue; |
| 358 | continue; | ||
| 359 | } | ||
| 360 | CollectStorageBuffers(*block, inst, storage_buffers, to_replace); | ||
| 361 | } | 358 | } |
| 359 | CollectStorageBuffers(*block, inst, storage_buffers, to_replace); | ||
| 362 | } | 360 | } |
| 363 | } | 361 | } |
| 364 | Info& info{program.info}; | 362 | Info& info{program.info}; |
diff --git a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp index 593efde39..8790b48f2 100644 --- a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp +++ b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp | |||
| @@ -10,10 +10,10 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Optimization { | 11 | namespace Shader::Optimization { |
| 12 | 12 | ||
| 13 | void IdentityRemovalPass(IR::Function& function) { | 13 | void IdentityRemovalPass(IR::Program& program) { |
| 14 | std::vector<IR::Inst*> to_invalidate; | 14 | std::vector<IR::Inst*> to_invalidate; |
| 15 | 15 | ||
| 16 | for (IR::Block* const block : function.blocks) { | 16 | for (IR::Block* const block : program.blocks) { |
| 17 | for (auto inst = block->begin(); inst != block->end();) { | 17 | for (auto inst = block->begin(); inst != block->end();) { |
| 18 | const size_t num_args{inst->NumArgs()}; | 18 | const size_t num_args{inst->NumArgs()}; |
| 19 | for (size_t i = 0; i < num_args; ++i) { | 19 | for (size_t i = 0; i < num_args; ++i) { |
diff --git a/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp b/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp index 14a5cb50f..74acb8bb6 100644 --- a/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp +++ b/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp | |||
| @@ -77,11 +77,9 @@ IR::Opcode Replace(IR::Opcode op) { | |||
| 77 | } // Anonymous namespace | 77 | } // Anonymous namespace |
| 78 | 78 | ||
| 79 | void LowerFp16ToFp32(IR::Program& program) { | 79 | void LowerFp16ToFp32(IR::Program& program) { |
| 80 | for (IR::Function& function : program.functions) { | 80 | for (IR::Block* const block : program.blocks) { |
| 81 | for (IR::Block* const block : function.blocks) { | 81 | for (IR::Inst& inst : block->Instructions()) { |
| 82 | for (IR::Inst& inst : block->Instructions()) { | 82 | inst.ReplaceOpcode(Replace(inst.Opcode())); |
| 83 | inst.ReplaceOpcode(Replace(inst.Opcode())); | ||
| 84 | } | ||
| 85 | } | 83 | } |
| 86 | } | 84 | } |
| 87 | } | 85 | } |
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h index 3b7e7306b..5c1fc166c 100644 --- a/src/shader_recompiler/ir_opt/passes.h +++ b/src/shader_recompiler/ir_opt/passes.h | |||
| @@ -8,26 +8,18 @@ | |||
| 8 | 8 | ||
| 9 | #include "shader_recompiler/environment.h" | 9 | #include "shader_recompiler/environment.h" |
| 10 | #include "shader_recompiler/frontend/ir/basic_block.h" | 10 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 11 | #include "shader_recompiler/frontend/ir/function.h" | ||
| 12 | #include "shader_recompiler/frontend/ir/program.h" | 11 | #include "shader_recompiler/frontend/ir/program.h" |
| 13 | 12 | ||
| 14 | namespace Shader::Optimization { | 13 | namespace Shader::Optimization { |
| 15 | 14 | ||
| 16 | template <typename Func> | ||
| 17 | void PostOrderInvoke(Func&& func, IR::Function& function) { | ||
| 18 | for (const auto& block : function.post_order_blocks) { | ||
| 19 | func(*block); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | void CollectShaderInfoPass(IR::Program& program); | 15 | void CollectShaderInfoPass(IR::Program& program); |
| 24 | void ConstantPropagationPass(IR::Block& block); | 16 | void ConstantPropagationPass(IR::Program& program); |
| 25 | void DeadCodeEliminationPass(IR::Block& block); | 17 | void DeadCodeEliminationPass(IR::Program& program); |
| 26 | void GlobalMemoryToStorageBufferPass(IR::Program& program); | 18 | void GlobalMemoryToStorageBufferPass(IR::Program& program); |
| 27 | void IdentityRemovalPass(IR::Function& function); | 19 | void IdentityRemovalPass(IR::Program& program); |
| 28 | void LowerFp16ToFp32(IR::Program& program); | 20 | void LowerFp16ToFp32(IR::Program& program); |
| 29 | void SsaRewritePass(std::span<IR::Block* const> post_order_blocks); | 21 | void SsaRewritePass(IR::Program& program); |
| 30 | void TexturePass(Environment& env, IR::Program& program); | 22 | void TexturePass(Environment& env, IR::Program& program); |
| 31 | void VerificationPass(const IR::Function& function); | 23 | void VerificationPass(const IR::Program& program); |
| 32 | 24 | ||
| 33 | } // namespace Shader::Optimization | 25 | } // 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 19d35b1f8..f89fd51c8 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <boost/container/flat_set.hpp> | 23 | #include <boost/container/flat_set.hpp> |
| 24 | 24 | ||
| 25 | #include "shader_recompiler/frontend/ir/basic_block.h" | 25 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 26 | #include "shader_recompiler/frontend/ir/function.h" | ||
| 27 | #include "shader_recompiler/frontend/ir/microinstruction.h" | 26 | #include "shader_recompiler/frontend/ir/microinstruction.h" |
| 28 | #include "shader_recompiler/frontend/ir/opcodes.h" | 27 | #include "shader_recompiler/frontend/ir/opcodes.h" |
| 29 | #include "shader_recompiler/frontend/ir/pred.h" | 28 | #include "shader_recompiler/frontend/ir/pred.h" |
| @@ -262,9 +261,9 @@ void VisitBlock(Pass& pass, IR::Block* block) { | |||
| 262 | } | 261 | } |
| 263 | } // Anonymous namespace | 262 | } // Anonymous namespace |
| 264 | 263 | ||
| 265 | void SsaRewritePass(std::span<IR::Block* const> post_order_blocks) { | 264 | void SsaRewritePass(IR::Program& program) { |
| 266 | Pass pass; | 265 | Pass pass; |
| 267 | for (IR::Block* const block : post_order_blocks | std::views::reverse) { | 266 | for (IR::Block* const block : program.post_order_blocks | std::views::reverse) { |
| 268 | VisitBlock(pass, block); | 267 | VisitBlock(pass, block); |
| 269 | } | 268 | } |
| 270 | } | 269 | } |
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index ec802e02c..de9d633e2 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp | |||
| @@ -164,14 +164,12 @@ private: | |||
| 164 | 164 | ||
| 165 | void TexturePass(Environment& env, IR::Program& program) { | 165 | void TexturePass(Environment& env, IR::Program& program) { |
| 166 | TextureInstVector to_replace; | 166 | TextureInstVector to_replace; |
| 167 | for (IR::Function& function : program.functions) { | 167 | for (IR::Block* const block : program.post_order_blocks) { |
| 168 | for (IR::Block* const block : function.post_order_blocks) { | 168 | for (IR::Inst& inst : block->Instructions()) { |
| 169 | for (IR::Inst& inst : block->Instructions()) { | 169 | if (!IsTextureInstruction(inst)) { |
| 170 | if (!IsTextureInstruction(inst)) { | 170 | continue; |
| 171 | continue; | ||
| 172 | } | ||
| 173 | to_replace.push_back(MakeInst(env, block, inst)); | ||
| 174 | } | 171 | } |
| 172 | to_replace.push_back(MakeInst(env, block, inst)); | ||
| 175 | } | 173 | } |
| 176 | } | 174 | } |
| 177 | // Sort instructions to visit textures by constant buffer index, then by offset | 175 | // Sort instructions to visit textures by constant buffer index, then by offset |
diff --git a/src/shader_recompiler/ir_opt/verification_pass.cpp b/src/shader_recompiler/ir_opt/verification_pass.cpp index 32b56eb57..4080b37cc 100644 --- a/src/shader_recompiler/ir_opt/verification_pass.cpp +++ b/src/shader_recompiler/ir_opt/verification_pass.cpp | |||
| @@ -11,8 +11,8 @@ | |||
| 11 | 11 | ||
| 12 | namespace Shader::Optimization { | 12 | namespace Shader::Optimization { |
| 13 | 13 | ||
| 14 | static void ValidateTypes(const IR::Function& function) { | 14 | static void ValidateTypes(const IR::Program& program) { |
| 15 | for (const auto& block : function.blocks) { | 15 | for (const auto& block : program.blocks) { |
| 16 | for (const IR::Inst& inst : *block) { | 16 | for (const IR::Inst& inst : *block) { |
| 17 | if (inst.Opcode() == IR::Opcode::Phi) { | 17 | if (inst.Opcode() == IR::Opcode::Phi) { |
| 18 | // Skip validation on phi nodes | 18 | // Skip validation on phi nodes |
| @@ -30,9 +30,9 @@ static void ValidateTypes(const IR::Function& function) { | |||
| 30 | } | 30 | } |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | static void ValidateUses(const IR::Function& function) { | 33 | static void ValidateUses(const IR::Program& program) { |
| 34 | std::map<IR::Inst*, int> actual_uses; | 34 | std::map<IR::Inst*, int> actual_uses; |
| 35 | for (const auto& block : function.blocks) { | 35 | for (const auto& block : program.blocks) { |
| 36 | for (const IR::Inst& inst : *block) { | 36 | for (const IR::Inst& inst : *block) { |
| 37 | const size_t num_args{inst.NumArgs()}; | 37 | const size_t num_args{inst.NumArgs()}; |
| 38 | for (size_t i = 0; i < num_args; ++i) { | 38 | for (size_t i = 0; i < num_args; ++i) { |
| @@ -45,14 +45,14 @@ static void ValidateUses(const IR::Function& function) { | |||
| 45 | } | 45 | } |
| 46 | for (const auto [inst, uses] : actual_uses) { | 46 | for (const auto [inst, uses] : actual_uses) { |
| 47 | if (inst->UseCount() != uses) { | 47 | if (inst->UseCount() != uses) { |
| 48 | throw LogicError("Invalid uses in block:" /*, IR::DumpFunction(function)*/); | 48 | throw LogicError("Invalid uses in block: {}", IR::DumpProgram(program)); |
| 49 | } | 49 | } |
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void VerificationPass(const IR::Function& function) { | 53 | void VerificationPass(const IR::Program& program) { |
| 54 | ValidateTypes(function); | 54 | ValidateTypes(program); |
| 55 | ValidateUses(function); | 55 | ValidateUses(program); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | } // namespace Shader::Optimization | 58 | } // namespace Shader::Optimization |