reg_alloc: Add the ability to Release an allocation early
This commit is contained in:
parent
e68bd3c6c1
commit
a12afd1065
2 changed files with 36 additions and 13 deletions
|
@ -83,25 +83,25 @@ static bool IsValuelessType(IR::Type type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostLocInfo::IsLocked() const {
|
bool HostLocInfo::IsLocked() const {
|
||||||
return is_being_used;
|
return is_being_used_count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostLocInfo::IsEmpty() const {
|
bool HostLocInfo::IsEmpty() const {
|
||||||
return !is_being_used && values.empty();
|
return is_being_used_count == 0 && values.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostLocInfo::IsLastUse() const {
|
bool HostLocInfo::IsLastUse() const {
|
||||||
return !is_being_used && current_references == 1 && accumulated_uses + 1 == total_uses;
|
return is_being_used_count == 0 && current_references == 1 && accumulated_uses + 1 == total_uses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostLocInfo::ReadLock() {
|
void HostLocInfo::ReadLock() {
|
||||||
ASSERT(!is_scratch);
|
ASSERT(!is_scratch);
|
||||||
is_being_used = true;
|
is_being_used_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostLocInfo::WriteLock() {
|
void HostLocInfo::WriteLock() {
|
||||||
ASSERT(!is_being_used);
|
ASSERT(is_being_used_count == 0);
|
||||||
is_being_used = true;
|
is_being_used_count++;
|
||||||
is_scratch = true;
|
is_scratch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +110,26 @@ void HostLocInfo::AddArgReference() {
|
||||||
ASSERT(accumulated_uses + current_references <= total_uses);
|
ASSERT(accumulated_uses + current_references <= total_uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostLocInfo::EndOfAllocScope() {
|
void HostLocInfo::ReleaseOne() {
|
||||||
|
is_being_used_count--;
|
||||||
|
is_scratch = false;
|
||||||
|
|
||||||
|
if (current_references == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
accumulated_uses++;
|
||||||
|
current_references--;
|
||||||
|
|
||||||
|
if (current_references == 0)
|
||||||
|
ReleaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HostLocInfo::ReleaseAll() {
|
||||||
accumulated_uses += current_references;
|
accumulated_uses += current_references;
|
||||||
current_references = 0;
|
current_references = 0;
|
||||||
|
|
||||||
|
ASSERT(total_uses == std::accumulate(values.begin(), values.end(), size_t(0), [](size_t sum, IR::Inst* inst) { return sum + inst->UseCount(); }));
|
||||||
|
|
||||||
if (total_uses == accumulated_uses) {
|
if (total_uses == accumulated_uses) {
|
||||||
values.clear();
|
values.clear();
|
||||||
accumulated_uses = 0;
|
accumulated_uses = 0;
|
||||||
|
@ -121,9 +137,7 @@ void HostLocInfo::EndOfAllocScope() {
|
||||||
max_bit_width = 0;
|
max_bit_width = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(total_uses == std::accumulate(values.begin(), values.end(), size_t(0), [](size_t sum, IR::Inst* inst) { return sum + inst->UseCount(); }));
|
is_being_used_count = 0;
|
||||||
|
|
||||||
is_being_used = false;
|
|
||||||
is_scratch = false;
|
is_scratch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +301,12 @@ void RegAlloc::DefineValue(IR::Inst* inst, Argument& arg) {
|
||||||
DefineValueImpl(inst, arg.value);
|
DefineValueImpl(inst, arg.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegAlloc::Release(const Xbyak::Reg& reg) {
|
||||||
|
ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
|
||||||
|
const HostLoc hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX));
|
||||||
|
LocInfo(hostloc).ReleaseOne();
|
||||||
|
}
|
||||||
|
|
||||||
Xbyak::Reg64 RegAlloc::ScratchGpr(HostLocList desired_locations) {
|
Xbyak::Reg64 RegAlloc::ScratchGpr(HostLocList desired_locations) {
|
||||||
return HostLocToReg64(ScratchImpl(desired_locations));
|
return HostLocToReg64(ScratchImpl(desired_locations));
|
||||||
}
|
}
|
||||||
|
@ -413,7 +433,7 @@ void RegAlloc::HostCall(IR::Inst* result_def, boost::optional<Argument&> arg0, b
|
||||||
|
|
||||||
void RegAlloc::EndOfAllocScope() {
|
void RegAlloc::EndOfAllocScope() {
|
||||||
for (auto& iter : hostloc_info) {
|
for (auto& iter : hostloc_info) {
|
||||||
iter.EndOfAllocScope();
|
iter.ReleaseAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ public:
|
||||||
void ReadLock();
|
void ReadLock();
|
||||||
void WriteLock();
|
void WriteLock();
|
||||||
void AddArgReference();
|
void AddArgReference();
|
||||||
void EndOfAllocScope();
|
void ReleaseOne();
|
||||||
|
void ReleaseAll();
|
||||||
|
|
||||||
bool ContainsValue(const IR::Inst* inst) const;
|
bool ContainsValue(const IR::Inst* inst) const;
|
||||||
size_t GetMaxBitWidth() const;
|
size_t GetMaxBitWidth() const;
|
||||||
|
@ -44,7 +45,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Current instruction state
|
// Current instruction state
|
||||||
bool is_being_used = false;
|
size_t is_being_used_count = 0;
|
||||||
bool is_scratch = false;
|
bool is_scratch = false;
|
||||||
|
|
||||||
// Block state
|
// Block state
|
||||||
|
@ -111,6 +112,8 @@ public:
|
||||||
void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg);
|
void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg);
|
||||||
void DefineValue(IR::Inst* inst, Argument& arg);
|
void DefineValue(IR::Inst* inst, Argument& arg);
|
||||||
|
|
||||||
|
void Release(const Xbyak::Reg& reg);
|
||||||
|
|
||||||
Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr);
|
Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr);
|
||||||
Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm);
|
Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue