backend/rv64: Implement UpdateAllUses

This commit is contained in:
Yang Liu 2024-01-20 17:19:54 +08:00 committed by Merry
parent cc2a6fd6fb
commit 3ff8b9d346
3 changed files with 35 additions and 31 deletions

View file

@ -95,6 +95,7 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
}
}
reg_alloc.UpdateAllUses();
reg_alloc.AssertNoMoreUses();
// TODO: Add Cycles

View file

@ -82,7 +82,18 @@ void HostLocInfo::SetupScratchLocation() {
}
bool HostLocInfo::IsCompletelyEmpty() const {
return values.empty() && !locked && !realized && !accumulated_uses && !expected_uses;
return values.empty() && !locked && !realized && !accumulated_uses && !expected_uses && !uses_this_inst;
}
void HostLocInfo::UpdateUses() {
accumulated_uses += uses_this_inst;
uses_this_inst = 0;
if (accumulated_uses == expected_uses) {
values.clear();
accumulated_uses = 0;
expected_uses = 0;
}
}
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
@ -92,7 +103,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT_MSG(ValueLocation(arg.GetInst()), "argument must already been defined");
ValueInfo(arg.GetInst()).accumulated_uses++;
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
return ret;
@ -102,8 +113,20 @@ bool RegAlloc::IsValueLive(IR::Inst* inst) const {
return !!ValueLocation(inst);
}
void RegAlloc::UpdateAllUses() {
for (auto& gpr : gprs) {
gpr.UpdateUses();
}
for (auto& fpr : fprs) {
fpr.UpdateUses();
}
for (auto& spill : spills) {
spill.UpdateUses();
}
}
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; };
const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
@ -224,20 +247,6 @@ template u32 RegAlloc::RealizeReadImpl<HostLoc::Kind::Fpr>(const IR::Value& valu
template u32 RegAlloc::RealizeWriteImpl<HostLoc::Kind::Gpr>(const IR::Inst* value);
template u32 RegAlloc::RealizeWriteImpl<HostLoc::Kind::Fpr>(const IR::Inst* value);
void RegAlloc::Unlock(HostLoc host_loc) {
HostLocInfo& info = ValueInfo(host_loc);
if (!info.realized) {
return;
}
if (info.accumulated_uses == info.expected_uses) {
info = {};
} else {
info.realized = false;
info.locked = false;
}
}
u32 RegAlloc::AllocateRegister(const std::array<HostLocInfo, 32>& regs, const std::vector<u32>& order) const {
const auto empty = std::find_if(order.begin(), order.end(), [&](u32 i) { return regs[i].values.empty() && !regs[i].locked; });
if (empty != order.end()) {

View file

@ -92,12 +92,14 @@ struct HostLocInfo final {
std::vector<const IR::Inst*> values;
size_t locked = 0;
bool realized = false;
size_t uses_this_inst = 0;
size_t accumulated_uses = 0;
size_t expected_uses = 0;
bool Contains(const IR::Inst*) const;
void SetupScratchLocation();
bool IsCompletelyEmpty() const;
void UpdateUses();
};
class RegAlloc {
@ -124,6 +126,7 @@ public:
(rs.Realize(), ...);
}
void UpdateAllUses();
void AssertNoMoreUses() const;
private:
@ -136,7 +139,6 @@ private:
u32 RealizeReadImpl(const IR::Value& value);
template<HostLoc::Kind kind>
u32 RealizeWriteImpl(const IR::Inst* value);
void Unlock(HostLoc host_loc);
u32 AllocateRegister(const std::array<HostLocInfo, 32>& regs, const std::vector<u32>& order) const;
void SpillGpr(u32 index);
@ -168,19 +170,11 @@ RAReg<T>::RAReg(RegAlloc& reg_alloc, bool write, const IR::Value& value)
template<typename T>
RAReg<T>::~RAReg() {
if (value.IsImmediate()) {
if (reg) {
// Immediate in scratch register
HostLocInfo& info = reg_alloc.ValueInfo(HostLoc{kind, reg->Index()});
info.locked--;
info.realized = false;
}
} else {
HostLocInfo& info = reg_alloc.ValueInfo(value.GetInst());
info.locked--;
if (reg) {
info.realized = false;
}
if (!value.IsImmediate()) {
reg_alloc.ValueInfo(value.GetInst()).locked--;
}
if (reg) {
reg_alloc.ValueInfo(HostLoc{kind, reg->Index()}).realized = false;
}
}