mirror of
https://git.suyu.dev/suyu/dynarmic
synced 2024-11-21 14:29:03 -07:00
backend/rv64: Implement UpdateAllUses
This commit is contained in:
parent
cc2a6fd6fb
commit
3ff8b9d346
3 changed files with 35 additions and 31 deletions
|
@ -95,6 +95,7 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
|
|||
}
|
||||
}
|
||||
|
||||
reg_alloc.UpdateAllUses();
|
||||
reg_alloc.AssertNoMoreUses();
|
||||
|
||||
// TODO: Add Cycles
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue