From 9b2391ec7bfd16deb23f3d4d93e84918820b8f59 Mon Sep 17 00:00:00 2001 From: Merry Date: Wed, 20 Jul 2022 18:17:11 +0100 Subject: [PATCH] backend/arm64/reg_alloc: Implement AssertNoMoreUses --- src/dynarmic/backend/arm64/emit_arm64.cpp | 3 +++ src/dynarmic/backend/arm64/reg_alloc.cpp | 20 ++++++++++++++++---- src/dynarmic/backend/arm64/reg_alloc.h | 7 +++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/dynarmic/backend/arm64/emit_arm64.cpp b/src/dynarmic/backend/arm64/emit_arm64.cpp index 76ed3c72..c139b93a 100644 --- a/src/dynarmic/backend/arm64/emit_arm64.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64.cpp @@ -40,6 +40,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitCon template<> void EmitIR(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) { + [[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst); ASSERT(ctx.reg_alloc.IsValueLive(inst)); } @@ -90,6 +91,8 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E } } + reg_alloc.AssertNoMoreUses(); + // TODO: Add Cycles // TODO: Emit Terminal diff --git a/src/dynarmic/backend/arm64/reg_alloc.cpp b/src/dynarmic/backend/arm64/reg_alloc.cpp index 55e2687d..f60d4faa 100644 --- a/src/dynarmic/backend/arm64/reg_alloc.cpp +++ b/src/dynarmic/backend/arm64/reg_alloc.cpp @@ -71,6 +71,10 @@ IR::AccType Argument::GetImmediateAccType() const { return value.GetAccType(); } +bool HostLocInfo::Contains(const IR::Inst* value) const { + return std::find(values.begin(), values.end(), value) != values.end(); +} + RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) { ArgumentInfo ret = {Argument{*this}, Argument{*this}, Argument{*this}, Argument{*this}}; for (size_t i = 0; i < inst->NumArgs(); i++) { @@ -88,6 +92,14 @@ bool RegAlloc::IsValueLive(IR::Inst* inst) const { return !!ValueLocation(inst); } +void RegAlloc::AssertNoMoreUses() const { + const auto is_empty = [](const auto& i) { return i.values.empty() && !i.locked && !i.realized && !i.accumulated_uses && !i.expected_uses; }; + ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty)); + ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty)); + ASSERT(is_empty(flags)); + ASSERT(std::all_of(spills.begin(), spills.end(), is_empty)); +} + template int RegAlloc::RealizeReadImpl(const IR::Inst* value) { const auto current_location = ValueLocation(value); @@ -159,10 +171,10 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) { const auto setup_location = [&](HostLocInfo& info) { info = {}; - info.values.emplace(value); + info.values.emplace_back(value); info.locked = true; info.realized = true; - info.expected_uses += value->UseCount(); + info.expected_uses = value->UseCount(); }; if constexpr (kind == HostLoc::Kind::Gpr) { @@ -258,7 +270,7 @@ int RegAlloc::FindFreeSpill() const { std::optional RegAlloc::ValueLocation(const IR::Inst* value) const { const auto contains_value = [value](const HostLocInfo& info) { - return info.values.contains(value); + return info.Contains(value); }; if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) { @@ -292,7 +304,7 @@ HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) { HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) { const auto contains_value = [value](const HostLocInfo& info) { - return info.values.contains(value); + return info.Contains(value); }; if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) { diff --git a/src/dynarmic/backend/arm64/reg_alloc.h b/src/dynarmic/backend/arm64/reg_alloc.h index 0ca9b7c2..b34d8059 100644 --- a/src/dynarmic/backend/arm64/reg_alloc.h +++ b/src/dynarmic/backend/arm64/reg_alloc.h @@ -15,7 +15,6 @@ #include #include #include -#include #include "dynarmic/backend/arm64/stack_layout.h" #include "dynarmic/ir/cond.h" @@ -108,11 +107,13 @@ private: }; struct HostLocInfo { - tsl::robin_set values; + std::vector values; bool locked = false; bool realized = false; size_t accumulated_uses = 0; size_t expected_uses = 0; + + bool Contains(const IR::Inst*) const; }; class RegAlloc { @@ -212,6 +213,8 @@ public: (rs.Realize(), ...); } + void AssertNoMoreUses() const; + private: template friend struct RAReg;