mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2025-06-12 10:07:56 -05:00
shader: Implement CAL inlining function calls
This commit is contained in:
@ -296,11 +296,9 @@ void Visit(Info& info, IR::Inst& inst) {
|
||||
|
||||
void CollectShaderInfoPass(IR::Program& program) {
|
||||
Info& info{program.info};
|
||||
for (IR::Function& function : program.functions) {
|
||||
for (IR::Block* const block : function.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
Visit(info, inst);
|
||||
}
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
Visit(info, inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,9 +371,11 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void ConstantPropagationPass(IR::Block& block) {
|
||||
for (IR::Inst& inst : block) {
|
||||
ConstantPropagation(block, inst);
|
||||
void ConstantPropagationPass(IR::Program& program) {
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
ConstantPropagation(*block, inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,12 +10,14 @@
|
||||
|
||||
namespace Shader::Optimization {
|
||||
|
||||
void DeadCodeEliminationPass(IR::Block& block) {
|
||||
void DeadCodeEliminationPass(IR::Program& program) {
|
||||
// We iterate over the instructions in reverse order.
|
||||
// This is because removing an instruction reduces the number of uses for earlier instructions.
|
||||
for (IR::Inst& inst : block | std::views::reverse) {
|
||||
if (!inst.HasUses() && !inst.MayHaveSideEffects()) {
|
||||
inst.Invalidate();
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions() | std::views::reverse) {
|
||||
if (!inst.HasUses() && !inst.MayHaveSideEffects()) {
|
||||
inst.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -351,14 +351,12 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) {
|
||||
StorageBufferSet storage_buffers;
|
||||
StorageInstVector to_replace;
|
||||
|
||||
for (IR::Function& function : program.functions) {
|
||||
for (IR::Block* const block : function.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
if (!IsGlobalMemory(inst)) {
|
||||
continue;
|
||||
}
|
||||
CollectStorageBuffers(*block, inst, storage_buffers, to_replace);
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
if (!IsGlobalMemory(inst)) {
|
||||
continue;
|
||||
}
|
||||
CollectStorageBuffers(*block, inst, storage_buffers, to_replace);
|
||||
}
|
||||
}
|
||||
Info& info{program.info};
|
||||
|
@ -10,10 +10,10 @@
|
||||
|
||||
namespace Shader::Optimization {
|
||||
|
||||
void IdentityRemovalPass(IR::Function& function) {
|
||||
void IdentityRemovalPass(IR::Program& program) {
|
||||
std::vector<IR::Inst*> to_invalidate;
|
||||
|
||||
for (IR::Block* const block : function.blocks) {
|
||||
for (IR::Block* const block : program.blocks) {
|
||||
for (auto inst = block->begin(); inst != block->end();) {
|
||||
const size_t num_args{inst->NumArgs()};
|
||||
for (size_t i = 0; i < num_args; ++i) {
|
||||
|
@ -77,11 +77,9 @@ IR::Opcode Replace(IR::Opcode op) {
|
||||
} // Anonymous namespace
|
||||
|
||||
void LowerFp16ToFp32(IR::Program& program) {
|
||||
for (IR::Function& function : program.functions) {
|
||||
for (IR::Block* const block : function.blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
inst.ReplaceOpcode(Replace(inst.Opcode()));
|
||||
}
|
||||
for (IR::Block* const block : program.blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
inst.ReplaceOpcode(Replace(inst.Opcode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,26 +8,18 @@
|
||||
|
||||
#include "shader_recompiler/environment.h"
|
||||
#include "shader_recompiler/frontend/ir/basic_block.h"
|
||||
#include "shader_recompiler/frontend/ir/function.h"
|
||||
#include "shader_recompiler/frontend/ir/program.h"
|
||||
|
||||
namespace Shader::Optimization {
|
||||
|
||||
template <typename Func>
|
||||
void PostOrderInvoke(Func&& func, IR::Function& function) {
|
||||
for (const auto& block : function.post_order_blocks) {
|
||||
func(*block);
|
||||
}
|
||||
}
|
||||
|
||||
void CollectShaderInfoPass(IR::Program& program);
|
||||
void ConstantPropagationPass(IR::Block& block);
|
||||
void DeadCodeEliminationPass(IR::Block& block);
|
||||
void ConstantPropagationPass(IR::Program& program);
|
||||
void DeadCodeEliminationPass(IR::Program& program);
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program);
|
||||
void IdentityRemovalPass(IR::Function& function);
|
||||
void IdentityRemovalPass(IR::Program& program);
|
||||
void LowerFp16ToFp32(IR::Program& program);
|
||||
void SsaRewritePass(std::span<IR::Block* const> post_order_blocks);
|
||||
void SsaRewritePass(IR::Program& program);
|
||||
void TexturePass(Environment& env, IR::Program& program);
|
||||
void VerificationPass(const IR::Function& function);
|
||||
void VerificationPass(const IR::Program& program);
|
||||
|
||||
} // namespace Shader::Optimization
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <boost/container/flat_set.hpp>
|
||||
|
||||
#include "shader_recompiler/frontend/ir/basic_block.h"
|
||||
#include "shader_recompiler/frontend/ir/function.h"
|
||||
#include "shader_recompiler/frontend/ir/microinstruction.h"
|
||||
#include "shader_recompiler/frontend/ir/opcodes.h"
|
||||
#include "shader_recompiler/frontend/ir/pred.h"
|
||||
@ -262,9 +261,9 @@ void VisitBlock(Pass& pass, IR::Block* block) {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void SsaRewritePass(std::span<IR::Block* const> post_order_blocks) {
|
||||
void SsaRewritePass(IR::Program& program) {
|
||||
Pass pass;
|
||||
for (IR::Block* const block : post_order_blocks | std::views::reverse) {
|
||||
for (IR::Block* const block : program.post_order_blocks | std::views::reverse) {
|
||||
VisitBlock(pass, block);
|
||||
}
|
||||
}
|
||||
|
@ -164,14 +164,12 @@ private:
|
||||
|
||||
void TexturePass(Environment& env, IR::Program& program) {
|
||||
TextureInstVector to_replace;
|
||||
for (IR::Function& function : program.functions) {
|
||||
for (IR::Block* const block : function.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
if (!IsTextureInstruction(inst)) {
|
||||
continue;
|
||||
}
|
||||
to_replace.push_back(MakeInst(env, block, inst));
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
if (!IsTextureInstruction(inst)) {
|
||||
continue;
|
||||
}
|
||||
to_replace.push_back(MakeInst(env, block, inst));
|
||||
}
|
||||
}
|
||||
// Sort instructions to visit textures by constant buffer index, then by offset
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
namespace Shader::Optimization {
|
||||
|
||||
static void ValidateTypes(const IR::Function& function) {
|
||||
for (const auto& block : function.blocks) {
|
||||
static void ValidateTypes(const IR::Program& program) {
|
||||
for (const auto& block : program.blocks) {
|
||||
for (const IR::Inst& inst : *block) {
|
||||
if (inst.Opcode() == IR::Opcode::Phi) {
|
||||
// Skip validation on phi nodes
|
||||
@ -30,9 +30,9 @@ static void ValidateTypes(const IR::Function& function) {
|
||||
}
|
||||
}
|
||||
|
||||
static void ValidateUses(const IR::Function& function) {
|
||||
static void ValidateUses(const IR::Program& program) {
|
||||
std::map<IR::Inst*, int> actual_uses;
|
||||
for (const auto& block : function.blocks) {
|
||||
for (const auto& block : program.blocks) {
|
||||
for (const IR::Inst& inst : *block) {
|
||||
const size_t num_args{inst.NumArgs()};
|
||||
for (size_t i = 0; i < num_args; ++i) {
|
||||
@ -45,14 +45,14 @@ static void ValidateUses(const IR::Function& function) {
|
||||
}
|
||||
for (const auto [inst, uses] : actual_uses) {
|
||||
if (inst->UseCount() != uses) {
|
||||
throw LogicError("Invalid uses in block:" /*, IR::DumpFunction(function)*/);
|
||||
throw LogicError("Invalid uses in block: {}", IR::DumpProgram(program));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VerificationPass(const IR::Function& function) {
|
||||
ValidateTypes(function);
|
||||
ValidateUses(function);
|
||||
void VerificationPass(const IR::Program& program) {
|
||||
ValidateTypes(program);
|
||||
ValidateUses(program);
|
||||
}
|
||||
|
||||
} // namespace Shader::Optimization
|
||||
|
Reference in New Issue
Block a user