backend/arm64/reg_alloc: Implement AssertNoMoreUses
This commit is contained in:
parent
ecacb6cdc6
commit
9b2391ec7b
3 changed files with 24 additions and 6 deletions
|
@ -40,6 +40,7 @@ void EmitIR<IR::Opcode::MostSignificantBit>(oaknut::CodeGenerator& code, EmitCon
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetCarryFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
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));
|
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: Add Cycles
|
||||||
|
|
||||||
// TODO: Emit Terminal
|
// TODO: Emit Terminal
|
||||||
|
|
|
@ -71,6 +71,10 @@ IR::AccType Argument::GetImmediateAccType() const {
|
||||||
return value.GetAccType();
|
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) {
|
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
||||||
ArgumentInfo ret = {Argument{*this}, Argument{*this}, Argument{*this}, Argument{*this}};
|
ArgumentInfo ret = {Argument{*this}, Argument{*this}, Argument{*this}, Argument{*this}};
|
||||||
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
||||||
|
@ -88,6 +92,14 @@ bool RegAlloc::IsValueLive(IR::Inst* inst) const {
|
||||||
return !!ValueLocation(inst);
|
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>
|
template<HostLoc::Kind required_kind>
|
||||||
int RegAlloc::RealizeReadImpl(const IR::Inst* value) {
|
int RegAlloc::RealizeReadImpl(const IR::Inst* value) {
|
||||||
const auto current_location = ValueLocation(value);
|
const auto current_location = ValueLocation(value);
|
||||||
|
@ -159,10 +171,10 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
||||||
|
|
||||||
const auto setup_location = [&](HostLocInfo& info) {
|
const auto setup_location = [&](HostLocInfo& info) {
|
||||||
info = {};
|
info = {};
|
||||||
info.values.emplace(value);
|
info.values.emplace_back(value);
|
||||||
info.locked = true;
|
info.locked = true;
|
||||||
info.realized = true;
|
info.realized = true;
|
||||||
info.expected_uses += value->UseCount();
|
info.expected_uses = value->UseCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
if constexpr (kind == HostLoc::Kind::Gpr) {
|
if constexpr (kind == HostLoc::Kind::Gpr) {
|
||||||
|
@ -258,7 +270,7 @@ int RegAlloc::FindFreeSpill() const {
|
||||||
|
|
||||||
std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
|
std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
|
||||||
const auto contains_value = [value](const HostLocInfo& info) {
|
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()) {
|
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) {
|
HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
||||||
const auto contains_value = [value](const HostLocInfo& info) {
|
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()) {
|
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <mcl/stdint.hpp>
|
#include <mcl/stdint.hpp>
|
||||||
#include <mcl/type_traits/is_instance_of_template.hpp>
|
#include <mcl/type_traits/is_instance_of_template.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include <tsl/robin_set.h>
|
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||||
#include "dynarmic/ir/cond.h"
|
#include "dynarmic/ir/cond.h"
|
||||||
|
@ -108,11 +107,13 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HostLocInfo {
|
struct HostLocInfo {
|
||||||
tsl::robin_set<const IR::Inst*> values;
|
std::vector<const IR::Inst*> values;
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
bool realized = false;
|
bool realized = false;
|
||||||
size_t accumulated_uses = 0;
|
size_t accumulated_uses = 0;
|
||||||
size_t expected_uses = 0;
|
size_t expected_uses = 0;
|
||||||
|
|
||||||
|
bool Contains(const IR::Inst*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegAlloc {
|
class RegAlloc {
|
||||||
|
@ -212,6 +213,8 @@ public:
|
||||||
(rs.Realize(), ...);
|
(rs.Realize(), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssertNoMoreUses() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename>
|
template<typename>
|
||||||
friend struct RAReg;
|
friend struct RAReg;
|
||||||
|
|
Loading…
Reference in a new issue