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, 23 insertions, 19 deletions
diff --git a/src/shader_recompiler/ir_opt/verification_pass.cpp b/src/shader_recompiler/ir_opt/verification_pass.cpp
index 36d9ae39b..8a5adf5a2 100644
--- a/src/shader_recompiler/ir_opt/verification_pass.cpp
+++ b/src/shader_recompiler/ir_opt/verification_pass.cpp
@@ -11,40 +11,44 @@
11 11
12namespace Shader::Optimization { 12namespace Shader::Optimization {
13 13
14static void ValidateTypes(const IR::Block& block) { 14static void ValidateTypes(const IR::Function& function) {
15 for (const IR::Inst& inst : block) { 15 for (const auto& block : function.blocks) {
16 const size_t num_args{inst.NumArgs()}; 16 for (const IR::Inst& inst : *block) {
17 for (size_t i = 0; i < num_args; ++i) { 17 const size_t num_args{inst.NumArgs()};
18 const IR::Type t1{inst.Arg(i).Type()}; 18 for (size_t i = 0; i < num_args; ++i) {
19 const IR::Type t2{IR::ArgTypeOf(inst.Opcode(), i)}; 19 const IR::Type t1{inst.Arg(i).Type()};
20 if (!IR::AreTypesCompatible(t1, t2)) { 20 const IR::Type t2{IR::ArgTypeOf(inst.Opcode(), i)};
21 throw LogicError("Invalid types in block:\n{}", IR::DumpBlock(block)); 21 if (!IR::AreTypesCompatible(t1, t2)) {
22 throw LogicError("Invalid types in block:\n{}", IR::DumpBlock(*block));
23 }
22 } 24 }
23 } 25 }
24 } 26 }
25} 27}
26 28
27static void ValidateUses(const IR::Block& block) { 29static void ValidateUses(const IR::Function& function) {
28 std::map<IR::Inst*, int> actual_uses; 30 std::map<IR::Inst*, int> actual_uses;
29 for (const IR::Inst& inst : block) { 31 for (const auto& block : function.blocks) {
30 const size_t num_args{inst.NumArgs()}; 32 for (const IR::Inst& inst : *block) {
31 for (size_t i = 0; i < num_args; ++i) { 33 const size_t num_args{inst.NumArgs()};
32 const IR::Value arg{inst.Arg(i)}; 34 for (size_t i = 0; i < num_args; ++i) {
33 if (!arg.IsImmediate()) { 35 const IR::Value arg{inst.Arg(i)};
34 ++actual_uses[arg.Inst()]; 36 if (!arg.IsImmediate()) {
37 ++actual_uses[arg.Inst()];
38 }
35 } 39 }
36 } 40 }
37 } 41 }
38 for (const auto [inst, uses] : actual_uses) { 42 for (const auto [inst, uses] : actual_uses) {
39 if (inst->UseCount() != uses) { 43 if (inst->UseCount() != uses) {
40 throw LogicError("Invalid uses in block:\n{}", IR::DumpBlock(block)); 44 throw LogicError("Invalid uses in block:" /*, IR::DumpFunction(function)*/);
41 } 45 }
42 } 46 }
43} 47}
44 48
45void VerificationPass(const IR::Block& block) { 49void VerificationPass(const IR::Function& function) {
46 ValidateTypes(block); 50 ValidateTypes(function);
47 ValidateUses(block); 51 ValidateUses(function);
48} 52}
49 53
50} // namespace Shader::Optimization 54} // namespace Shader::Optimization