backend/arm64/reg_alloc: Implement AssertNoMoreUses

This commit is contained in:
Merry 2022-07-20 18:17:11 +01:00 committed by merry
parent ecacb6cdc6
commit 9b2391ec7b
3 changed files with 24 additions and 6 deletions

View file

@ -40,6 +40,7 @@ void EmitIR<IR::Opcode::MostSignificantBit>(oaknut::CodeGenerator& code, EmitCon
template<>
void EmitIR<IR::Opcode::GetCarryFromOp>(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

View file

@ -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<HostLoc::Kind required_kind>
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<HostLoc> 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()) {

View file

@ -15,7 +15,6 @@
#include <mcl/stdint.hpp>
#include <mcl/type_traits/is_instance_of_template.hpp>
#include <oaknut/oaknut.hpp>
#include <tsl/robin_set.h>
#include "dynarmic/backend/arm64/stack_layout.h"
#include "dynarmic/ir/cond.h"
@ -108,11 +107,13 @@ private:
};
struct HostLocInfo {
tsl::robin_set<const IR::Inst*> values;
std::vector<const IR::Inst*> 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<typename>
friend struct RAReg;