summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/verification_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/ir_opt/verification_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/verification_pass.cpp42
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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map> 5#include <map>
6#include <set>
6 7
7#include "shader_recompiler/exception.h" 8#include "shader_recompiler/exception.h"
8#include "shader_recompiler/frontend/ir/basic_block.h" 9#include "shader_recompiler/frontend/ir/basic_block.h"
@@ -50,9 +51,50 @@ static void ValidateUses(const IR::Program& program) {
50 } 51 }
51} 52}
52 53
54static void ValidateForwardDeclarations(const IR::Program& program) {
55 std::set<const IR::Inst*> definitions;
56 for (const IR::Block* const block : program.blocks) {
57 for (const IR::Inst& inst : *block) {
58 definitions.emplace(&inst);
59 if (inst.GetOpcode() == IR::Opcode::Phi) {
60 // Phi nodes can have forward declarations
61 continue;
62 }
63 const size_t num_args{inst.NumArgs()};
64 for (size_t arg = 0; arg < num_args; ++arg) {
65 if (inst.Arg(arg).IsImmediate()) {
66 continue;
67 }
68 if (!definitions.contains(inst.Arg(arg).Inst())) {
69 fmt::print("{}\n", IR::DumpBlock(*block));
70 throw LogicError("Forward declaration in block: {}", IR::DumpBlock(*block));
71 }
72 }
73 }
74 }
75}
76
77static void ValidatePhiNodes(const IR::Program& program) {
78 for (const IR::Block* const block : program.blocks) {
79 bool no_more_phis{false};
80 for (const IR::Inst& inst : *block) {
81 if (inst.GetOpcode() == IR::Opcode::Phi) {
82 if (no_more_phis) {
83 fmt::print("{}\n", IR::DumpBlock(*block));
84 throw LogicError("Interleaved phi nodes: {}", IR::DumpBlock(*block));
85 }
86 } else {
87 no_more_phis = true;
88 }
89 }
90 }
91}
92
53void VerificationPass(const IR::Program& program) { 93void VerificationPass(const IR::Program& program) {
54 ValidateTypes(program); 94 ValidateTypes(program);
55 ValidateUses(program); 95 ValidateUses(program);
96 ValidateForwardDeclarations(program);
97 ValidatePhiNodes(program);
56} 98}
57 99
58} // namespace Shader::Optimization 100} // namespace Shader::Optimization