backend/x64/reg_alloc: Apply const where applicable

Also tidies up bracing where applicable along the way.
This commit is contained in:
Lioncash 2019-05-25 17:40:35 -04:00 committed by MerryMage
parent cba9351b82
commit 22bd95902d

View file

@ -282,7 +282,7 @@ void RegAlloc::UseScratch(Argument& arg, HostLoc host_loc) {
void RegAlloc::DefineValue(IR::Inst* inst, const Xbyak::Reg& reg) { void RegAlloc::DefineValue(IR::Inst* inst, const Xbyak::Reg& reg) {
ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG); ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
HostLoc hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX)); const auto hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX));
DefineValueImpl(inst, hostloc); DefineValueImpl(inst, hostloc);
} }
@ -294,7 +294,7 @@ void RegAlloc::DefineValue(IR::Inst* inst, Argument& arg) {
void RegAlloc::Release(const Xbyak::Reg& reg) { void RegAlloc::Release(const Xbyak::Reg& reg) {
ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::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)); const auto hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX));
LocInfo(hostloc).ReleaseOne(); LocInfo(hostloc).ReleaseOne();
} }
@ -364,7 +364,7 @@ HostLoc RegAlloc::UseScratchImpl(IR::Value use_value, HostLocList desired_locati
} }
HostLoc RegAlloc::ScratchImpl(HostLocList desired_locations) { HostLoc RegAlloc::ScratchImpl(HostLocList desired_locations) {
HostLoc location = SelectARegister(desired_locations); const HostLoc location = SelectARegister(desired_locations);
MoveOutOfTheWay(location); MoveOutOfTheWay(location);
LocInfo(location).WriteLock(); LocInfo(location).WriteLock();
return location; return location;
@ -382,8 +382,9 @@ void RegAlloc::HostCall(IR::Inst* result_def, std::optional<Argument::copyable_r
std::vector<HostLoc> ret(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end()); std::vector<HostLoc> ret(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end());
ret.erase(std::find(ret.begin(), ret.end(), ABI_RETURN)); ret.erase(std::find(ret.begin(), ret.end(), ABI_RETURN));
for (auto hostloc : args_hostloc) for (auto hostloc : args_hostloc) {
ret.erase(std::find(ret.begin(), ret.end(), hostloc)); ret.erase(std::find(ret.begin(), ret.end(), hostloc));
}
return ret; return ret;
}(); }();
@ -398,7 +399,7 @@ void RegAlloc::HostCall(IR::Inst* result_def, std::optional<Argument::copyable_r
UseScratch(*args[i], args_hostloc[i]); UseScratch(*args[i], args_hostloc[i]);
#if defined(__llvm__) && !defined(_WIN32) #if defined(__llvm__) && !defined(_WIN32)
// LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee // LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee
Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]); const Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]);
switch (args[i]->get().GetType()) { switch (args[i]->get().GetType()) {
case IR::Type::U8: case IR::Type::U8:
code.movzx(reg.cvt32(), reg.cvt8()); code.movzx(reg.cvt32(), reg.cvt8());
@ -439,7 +440,7 @@ HostLoc RegAlloc::SelectARegister(HostLocList desired_locations) const {
std::vector<HostLoc> candidates = desired_locations; std::vector<HostLoc> candidates = desired_locations;
// Find all locations that have not been allocated.. // Find all locations that have not been allocated..
auto allocated_locs = std::partition(candidates.begin(), candidates.end(), [this](auto loc){ const auto allocated_locs = std::partition(candidates.begin(), candidates.end(), [this](auto loc) {
return !this->LocInfo(loc).IsLocked(); return !this->LocInfo(loc).IsLocked();
}); });
candidates.erase(allocated_locs, candidates.end()); candidates.erase(allocated_locs, candidates.end());
@ -448,7 +449,7 @@ HostLoc RegAlloc::SelectARegister(HostLocList desired_locations) const {
// Selects the best location out of the available locations. // Selects the best location out of the available locations.
// TODO: Actually do LRU or something. Currently we just try to pick something without a value if possible. // TODO: Actually do LRU or something. Currently we just try to pick something without a value if possible.
std::partition(candidates.begin(), candidates.end(), [this](auto loc){ std::partition(candidates.begin(), candidates.end(), [this](auto loc) {
return this->LocInfo(loc).IsEmpty(); return this->LocInfo(loc).IsEmpty();
}); });
@ -456,9 +457,11 @@ HostLoc RegAlloc::SelectARegister(HostLocList desired_locations) const {
} }
std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const { std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
for (size_t i = 0; i < hostloc_info.size(); i++) for (size_t i = 0; i < hostloc_info.size(); i++) {
if (hostloc_info[i].ContainsValue(value)) if (hostloc_info[i].ContainsValue(value)) {
return static_cast<HostLoc>(i); return static_cast<HostLoc>(i);
}
}
return std::nullopt; return std::nullopt;
} }
@ -472,14 +475,14 @@ void RegAlloc::DefineValueImpl(IR::Inst* def_inst, const IR::Value& use_inst) {
ASSERT_MSG(!ValueLocation(def_inst), "def_inst has already been defined"); ASSERT_MSG(!ValueLocation(def_inst), "def_inst has already been defined");
if (use_inst.IsImmediate()) { if (use_inst.IsImmediate()) {
HostLoc location = ScratchImpl(any_gpr); const HostLoc location = ScratchImpl(any_gpr);
DefineValueImpl(def_inst, location); DefineValueImpl(def_inst, location);
LoadImmediate(use_inst, location); LoadImmediate(use_inst, location);
return; return;
} }
ASSERT_MSG(ValueLocation(use_inst.GetInst()), "use_inst must already be defined"); ASSERT_MSG(ValueLocation(use_inst.GetInst()), "use_inst must already be defined");
HostLoc location = *ValueLocation(use_inst.GetInst()); const HostLoc location = *ValueLocation(use_inst.GetInst());
DefineValueImpl(def_inst, location); DefineValueImpl(def_inst, location);
} }
@ -489,20 +492,22 @@ HostLoc RegAlloc::LoadImmediate(IR::Value imm, HostLoc host_loc) {
if (HostLocIsGPR(host_loc)) { if (HostLocIsGPR(host_loc)) {
const Xbyak::Reg64 reg = HostLocToReg64(host_loc); const Xbyak::Reg64 reg = HostLocToReg64(host_loc);
const u64 imm_value = imm.GetImmediateAsU64(); const u64 imm_value = imm.GetImmediateAsU64();
if (imm_value == 0) if (imm_value == 0) {
code.xor_(reg.cvt32(), reg.cvt32()); code.xor_(reg.cvt32(), reg.cvt32());
else } else {
code.mov(reg, imm_value); code.mov(reg, imm_value);
}
return host_loc; return host_loc;
} }
if (HostLocIsXMM(host_loc)) { if (HostLocIsXMM(host_loc)) {
const Xbyak::Xmm reg = HostLocToXmm(host_loc); const Xbyak::Xmm reg = HostLocToXmm(host_loc);
const u64 imm_value = imm.GetImmediateAsU64(); const u64 imm_value = imm.GetImmediateAsU64();
if (imm_value == 0) if (imm_value == 0) {
MAYBE_AVX(xorps, reg, reg); MAYBE_AVX(xorps, reg, reg);
else } else {
MAYBE_AVX(movaps, reg, code.MConst(code.xword, imm_value)); MAYBE_AVX(movaps, reg, code.MConst(code.xword, imm_value));
}
return host_loc; return host_loc;
} }
@ -562,15 +567,16 @@ void RegAlloc::SpillRegister(HostLoc loc) {
ASSERT_MSG(!LocInfo(loc).IsEmpty(), "There is no need to spill unoccupied registers"); ASSERT_MSG(!LocInfo(loc).IsEmpty(), "There is no need to spill unoccupied registers");
ASSERT_MSG(!LocInfo(loc).IsLocked(), "Registers that have been allocated must not be spilt"); ASSERT_MSG(!LocInfo(loc).IsLocked(), "Registers that have been allocated must not be spilt");
HostLoc new_loc = FindFreeSpill(); const HostLoc new_loc = FindFreeSpill();
Move(new_loc, loc); Move(new_loc, loc);
} }
HostLoc RegAlloc::FindFreeSpill() const { HostLoc RegAlloc::FindFreeSpill() const {
for (size_t i = static_cast<size_t>(HostLoc::FirstSpill); i < hostloc_info.size(); i++) { for (size_t i = static_cast<size_t>(HostLoc::FirstSpill); i < hostloc_info.size(); i++) {
HostLoc loc = static_cast<HostLoc>(i); const auto loc = static_cast<HostLoc>(i);
if (LocInfo(loc).IsEmpty()) if (LocInfo(loc).IsEmpty()) {
return loc; return loc;
}
} }
ASSERT_MSG(false, "All spill locations are full"); ASSERT_MSG(false, "All spill locations are full");
@ -611,7 +617,7 @@ void RegAlloc::EmitMove(size_t bit_width, HostLoc to, HostLoc from) {
MAYBE_AVX(movd, HostLocToReg64(to).cvt32(), HostLocToXmm(from)); MAYBE_AVX(movd, HostLocToReg64(to).cvt32(), HostLocToXmm(from));
} }
} else if (HostLocIsXMM(to) && HostLocIsSpill(from)) { } else if (HostLocIsXMM(to) && HostLocIsSpill(from)) {
Xbyak::Address spill_addr = spill_to_addr(from); const Xbyak::Address spill_addr = spill_to_addr(from);
ASSERT(spill_addr.getBit() >= bit_width); ASSERT(spill_addr.getBit() >= bit_width);
switch (bit_width) { switch (bit_width) {
case 128: case 128:
@ -629,7 +635,7 @@ void RegAlloc::EmitMove(size_t bit_width, HostLoc to, HostLoc from) {
UNREACHABLE(); UNREACHABLE();
} }
} else if (HostLocIsSpill(to) && HostLocIsXMM(from)) { } else if (HostLocIsSpill(to) && HostLocIsXMM(from)) {
Xbyak::Address spill_addr = spill_to_addr(to); const Xbyak::Address spill_addr = spill_to_addr(to);
ASSERT(spill_addr.getBit() >= bit_width); ASSERT(spill_addr.getBit() >= bit_width);
switch (bit_width) { switch (bit_width) {
case 128: case 128: