reg_alloc: Remove reliance on IR::Inst::DecrementRemainingUses
This commit is contained in:
parent
30049ca928
commit
6b122751fe
2 changed files with 26 additions and 5 deletions
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include <xbyak.h>
|
#include <xbyak.h>
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ bool HostLocInfo::IsEmpty() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostLocInfo::IsLastUse() const {
|
bool HostLocInfo::IsLastUse() const {
|
||||||
return !is_being_used && std::all_of(values.begin(), values.end(), [](const auto& inst) { return !inst->HasUses(); });
|
return !is_being_used && current_references == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostLocInfo::ContainsValue(const IR::Inst* inst) const {
|
bool HostLocInfo::ContainsValue(const IR::Inst* inst) const {
|
||||||
|
@ -100,11 +101,25 @@ void HostLocInfo::WriteLock() {
|
||||||
|
|
||||||
void HostLocInfo::AddValue(IR::Inst* inst) {
|
void HostLocInfo::AddValue(IR::Inst* inst) {
|
||||||
values.push_back(inst);
|
values.push_back(inst);
|
||||||
|
total_uses += inst->UseCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HostLocInfo::AddArgReference() {
|
||||||
|
current_references++;
|
||||||
|
ASSERT(accumulated_uses + current_references <= total_uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostLocInfo::EndOfAllocScope() {
|
void HostLocInfo::EndOfAllocScope() {
|
||||||
const auto to_erase = std::remove_if(values.begin(), values.end(), [](const auto& inst) { return !inst->HasUses(); });
|
accumulated_uses += current_references;
|
||||||
values.erase(to_erase, values.end());
|
current_references = 0;
|
||||||
|
|
||||||
|
if (total_uses == accumulated_uses) {
|
||||||
|
values.clear();
|
||||||
|
accumulated_uses = 0;
|
||||||
|
total_uses = 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 = false;
|
is_being_used = false;
|
||||||
is_scratch = false;
|
is_scratch = false;
|
||||||
|
@ -159,10 +174,11 @@ bool Argument::IsInMemory() const {
|
||||||
std::array<Argument, 3> RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
std::array<Argument, 3> RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
||||||
std::array<Argument, 3> ret = { Argument{*this}, Argument{*this}, Argument{*this} };
|
std::array<Argument, 3> ret = { Argument{*this}, Argument{*this}, Argument{*this} };
|
||||||
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
||||||
IR::Value arg = inst->GetArg(i);
|
const IR::Value& arg = inst->GetArg(i);
|
||||||
ret[i].value = arg;
|
ret[i].value = arg;
|
||||||
if (!arg.IsImmediate()) {
|
if (!arg.IsImmediate()) {
|
||||||
arg.GetInst()->DecrementRemainingUses();
|
ASSERT_MSG(ValueLocation(arg.GetInst()), "argument must already been defined");
|
||||||
|
LocInfo(*ValueLocation(arg.GetInst())).AddArgReference();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -37,12 +37,17 @@ public:
|
||||||
|
|
||||||
void AddValue(IR::Inst* inst);
|
void AddValue(IR::Inst* inst);
|
||||||
|
|
||||||
|
void AddArgReference();
|
||||||
void EndOfAllocScope();
|
void EndOfAllocScope();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<IR::Inst*> values;
|
std::vector<IR::Inst*> values;
|
||||||
bool is_being_used = false;
|
bool is_being_used = false;
|
||||||
bool is_scratch = false;
|
bool is_scratch = false;
|
||||||
|
|
||||||
|
size_t current_references = 0;
|
||||||
|
size_t accumulated_uses = 0;
|
||||||
|
size_t total_uses = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Argument {
|
struct Argument {
|
||||||
|
|
Loading…
Reference in a new issue