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.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/verification_pass.cpp b/src/shader_recompiler/ir_opt/verification_pass.cpp
new file mode 100644
index 000000000..36d9ae39b
--- /dev/null
+++ b/src/shader_recompiler/ir_opt/verification_pass.cpp
@@ -0,0 +1,50 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <map>
6
7#include "shader_recompiler/exception.h"
8#include "shader_recompiler/frontend/ir/basic_block.h"
9#include "shader_recompiler/frontend/ir/microinstruction.h"
10#include "shader_recompiler/ir_opt/passes.h"
11
12namespace Shader::Optimization {
13
14static void ValidateTypes(const IR::Block& block) {
15 for (const IR::Inst& inst : block) {
16 const size_t num_args{inst.NumArgs()};
17 for (size_t i = 0; i < num_args; ++i) {
18 const IR::Type t1{inst.Arg(i).Type()};
19 const IR::Type t2{IR::ArgTypeOf(inst.Opcode(), i)};
20 if (!IR::AreTypesCompatible(t1, t2)) {
21 throw LogicError("Invalid types in block:\n{}", IR::DumpBlock(block));
22 }
23 }
24 }
25}
26
27static void ValidateUses(const IR::Block& block) {
28 std::map<IR::Inst*, int> actual_uses;
29 for (const IR::Inst& inst : block) {
30 const size_t num_args{inst.NumArgs()};
31 for (size_t i = 0; i < num_args; ++i) {
32 const IR::Value arg{inst.Arg(i)};
33 if (!arg.IsImmediate()) {
34 ++actual_uses[arg.Inst()];
35 }
36 }
37 }
38 for (const auto [inst, uses] : actual_uses) {
39 if (inst->UseCount() != uses) {
40 throw LogicError("Invalid uses in block:\n{}", IR::DumpBlock(block));
41 }
42 }
43}
44
45void VerificationPass(const IR::Block& block) {
46 ValidateTypes(block);
47 ValidateUses(block);
48}
49
50} // namespace Shader::Optimization