reg_alloc: Reimplement UseScratchHostLocReg

This commit is contained in:
MerryMage 2017-02-24 19:58:16 +00:00
parent e1d8238c50
commit 9518bbe06e
2 changed files with 20 additions and 31 deletions

View file

@ -182,40 +182,22 @@ HostLoc RegAlloc::UseScratchHostLocReg(IR::Value use_value, HostLocList desired_
} }
HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_locations) { HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_locations) {
DEBUG_ASSERT(std::all_of(desired_locations.begin(), desired_locations.end(), HostLocIsRegister));
DEBUG_ASSERT_MSG(ValueLocation(use_inst), "use_inst has not been defined");
ASSERT_MSG(use_inst->HasUses(), "use_inst ran out of uses. (Use-d an IR::Inst* too many times)");
HostLoc current_location = *ValueLocation(use_inst);
HostLoc new_location = SelectARegister(desired_locations);
if (IsRegisterOccupied(new_location)) {
SpillRegister(new_location);
}
if (HostLocIsSpill(current_location)) {
EmitMove(code, new_location, current_location);
LocInfo(new_location).Lock();
use_inst->DecrementRemainingUses(); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(new_location).IsScratch());
return new_location;
} else if (HostLocIsRegister(current_location)) {
ASSERT(LocInfo(current_location).IsIdle()
|| LocInfo(current_location).IsUse());
if (current_location != new_location) { const HostLoc current_location = *ValueLocation(use_inst);
EmitMove(code, new_location, current_location);
} else { const bool can_use_current_location = std::find(desired_locations.begin(), desired_locations.end(), current_location) != desired_locations.end();
ASSERT(LocInfo(current_location).IsIdle()); if (can_use_current_location && !LocInfo(current_location).IsLocked()) {
MoveOutOfTheWay(current_location);
LocInfo(current_location).Lock();
return current_location;
} }
LocInfo(new_location) = {}; const HostLoc destination_location = SelectARegister(desired_locations);
LocInfo(new_location).Lock(); MoveOutOfTheWay(destination_location);
use_inst->DecrementRemainingUses(); CopyToScratch(destination_location, current_location);
DEBUG_ASSERT(LocInfo(new_location).IsScratch()); LocInfo(destination_location).Lock();
return new_location; return destination_location;
}
ASSERT_MSG(false, "Invalid current_location");
} }
HostLoc RegAlloc::ScratchHostLocReg(HostLocList desired_locations) { HostLoc RegAlloc::ScratchHostLocReg(HostLocList desired_locations) {
@ -418,6 +400,12 @@ void RegAlloc::Move(HostLoc to, HostLoc from) {
EmitMove(code, to, from); EmitMove(code, to, from);
} }
void RegAlloc::CopyToScratch(HostLoc to, HostLoc from) {
ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsEmpty());
EmitMove(code, to, from);
}
void RegAlloc::Exchange(HostLoc a, HostLoc b) { void RegAlloc::Exchange(HostLoc a, HostLoc b) {
ASSERT(!LocInfo(a).IsLocked() && !LocInfo(b).IsLocked()); ASSERT(!LocInfo(a).IsLocked() && !LocInfo(b).IsLocked());

View file

@ -156,6 +156,7 @@ private:
HostLoc LoadImmediateIntoHostLocReg(IR::Value imm, HostLoc reg); HostLoc LoadImmediateIntoHostLocReg(IR::Value imm, HostLoc reg);
void Move(HostLoc to, HostLoc from); void Move(HostLoc to, HostLoc from);
void CopyToScratch(HostLoc to, HostLoc from);
void Exchange(HostLoc a, HostLoc b); void Exchange(HostLoc a, HostLoc b);
void MoveOutOfTheWay(HostLoc reg); void MoveOutOfTheWay(HostLoc reg);