diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-04-22 23:34:34 +0200 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-23 03:51:29 +0200 |
commit | 0c7230a606ae705a28c8a14590808d6bfd3656cf (patch) | |
tree | 8b798882305a203b21a76d35448e5f0939e83dc0 | |
parent | shader: Fix forward referencing identity instructions when inserting phi (diff) | |
download | yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar.gz yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar.bz2 yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar.lz yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar.xz yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.tar.zst yuzu-0c7230a606ae705a28c8a14590808d6bfd3656cf.zip |
-rw-r--r-- | src/shader_recompiler/ir_opt/verification_pass.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/verification_pass.cpp b/src/shader_recompiler/ir_opt/verification_pass.cpp index 62bf5f8ff..207355ecc 100644 --- a/src/shader_recompiler/ir_opt/verification_pass.cpp +++ b/src/shader_recompiler/ir_opt/verification_pass.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <map> +#include <set> #include "shader_recompiler/exception.h" #include "shader_recompiler/frontend/ir/basic_block.h" @@ -50,9 +51,50 @@ static void ValidateUses(const IR::Program& program) { } } +static void ValidateForwardDeclarations(const IR::Program& program) { + std::set<const IR::Inst*> definitions; + for (const IR::Block* const block : program.blocks) { + for (const IR::Inst& inst : *block) { + definitions.emplace(&inst); + if (inst.GetOpcode() == IR::Opcode::Phi) { + // Phi nodes can have forward declarations + continue; + } + const size_t num_args{inst.NumArgs()}; + for (size_t arg = 0; arg < num_args; ++arg) { + if (inst.Arg(arg).IsImmediate()) { + continue; + } + if (!definitions.contains(inst.Arg(arg).Inst())) { + fmt::print("{}\n", IR::DumpBlock(*block)); + throw LogicError("Forward declaration in block: {}", IR::DumpBlock(*block)); + } + } + } + } +} + +static void ValidatePhiNodes(const IR::Program& program) { + for (const IR::Block* const block : program.blocks) { + bool no_more_phis{false}; + for (const IR::Inst& inst : *block) { + if (inst.GetOpcode() == IR::Opcode::Phi) { + if (no_more_phis) { + fmt::print("{}\n", IR::DumpBlock(*block)); + throw LogicError("Interleaved phi nodes: {}", IR::DumpBlock(*block)); + } + } else { + no_more_phis = true; + } + } + } +} + void VerificationPass(const IR::Program& program) { ValidateTypes(program); ValidateUses(program); + ValidateForwardDeclarations(program); + ValidatePhiNodes(program); } } // namespace Shader::Optimization |