diff options
Diffstat (limited to 'src/shader_recompiler/ir_opt/verification_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/verification_pass.cpp | 42 |
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 | ||
| 12 | namespace Shader::Optimization { | 12 | namespace Shader::Optimization { |
| 13 | 13 | ||
| 14 | static void ValidateTypes(const IR::Block& block) { | 14 | static 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 | ||
| 27 | static void ValidateUses(const IR::Block& block) { | 29 | static 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 | ||
| 45 | void VerificationPass(const IR::Block& block) { | 49 | void 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 |