aboutsummaryrefslogtreecommitdiff
path: root/externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp')
-rw-r--r--externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp
new file mode 100644
index 0000000000..8bc9e6f1f0
--- /dev/null
+++ b/externals/dynarmic/src/dynarmic/ir/opt/verification_pass.cpp
@@ -0,0 +1,47 @@
+/* This file is part of the dynarmic project.
+ * Copyright (c) 2016 MerryMage
+ * SPDX-License-Identifier: 0BSD
+ */
+
+#include <cstdio>
+#include <map>
+
+#include <mcl/assert.hpp>
+#include <mcl/stdint.hpp>
+
+#include "dynarmic/ir/basic_block.h"
+#include "dynarmic/ir/microinstruction.h"
+#include "dynarmic/ir/opcodes.h"
+#include "dynarmic/ir/opt/passes.h"
+#include "dynarmic/ir/type.h"
+
+namespace Dynarmic::Optimization {
+
+void VerificationPass(const IR::Block& block) {
+ for (const auto& inst : block) {
+ for (size_t i = 0; i < inst.NumArgs(); i++) {
+ const IR::Type t1 = inst.GetArg(i).GetType();
+ const IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i);
+ if (!IR::AreTypesCompatible(t1, t2)) {
+ std::puts(IR::DumpBlock(block).c_str());
+ ASSERT_FALSE("above block failed validation");
+ }
+ }
+ }
+
+ std::map<IR::Inst*, size_t> actual_uses;
+ for (const auto& inst : block) {
+ for (size_t i = 0; i < inst.NumArgs(); i++) {
+ const auto arg = inst.GetArg(i);
+ if (!arg.IsImmediate()) {
+ actual_uses[arg.GetInst()]++;
+ }
+ }
+ }
+
+ for (const auto& pair : actual_uses) {
+ ASSERT(pair.first->UseCount() == pair.second);
+ }
+}
+
+} // namespace Dynarmic::Optimization