reg_alloc: Reimplement UseScratchHostLocReg
This commit is contained in:
parent
e1d8238c50
commit
9518bbe06e
2 changed files with 20 additions and 31 deletions
|
@ -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));
|
use_inst->DecrementRemainingUses();
|
||||||
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);
|
const HostLoc current_location = *ValueLocation(use_inst);
|
||||||
HostLoc new_location = SelectARegister(desired_locations);
|
|
||||||
if (IsRegisterOccupied(new_location)) {
|
const bool can_use_current_location = std::find(desired_locations.begin(), desired_locations.end(), current_location) != desired_locations.end();
|
||||||
SpillRegister(new_location);
|
if (can_use_current_location && !LocInfo(current_location).IsLocked()) {
|
||||||
|
MoveOutOfTheWay(current_location);
|
||||||
|
LocInfo(current_location).Lock();
|
||||||
|
return current_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HostLocIsSpill(current_location)) {
|
const HostLoc destination_location = SelectARegister(desired_locations);
|
||||||
EmitMove(code, new_location, current_location);
|
MoveOutOfTheWay(destination_location);
|
||||||
LocInfo(new_location).Lock();
|
CopyToScratch(destination_location, current_location);
|
||||||
use_inst->DecrementRemainingUses();
|
LocInfo(destination_location).Lock();
|
||||||
DEBUG_ASSERT(LocInfo(new_location).IsScratch());
|
return destination_location;
|
||||||
return new_location;
|
|
||||||
} else if (HostLocIsRegister(current_location)) {
|
|
||||||
ASSERT(LocInfo(current_location).IsIdle()
|
|
||||||
|| LocInfo(current_location).IsUse());
|
|
||||||
|
|
||||||
if (current_location != new_location) {
|
|
||||||
EmitMove(code, new_location, current_location);
|
|
||||||
} else {
|
|
||||||
ASSERT(LocInfo(current_location).IsIdle());
|
|
||||||
}
|
|
||||||
|
|
||||||
LocInfo(new_location) = {};
|
|
||||||
LocInfo(new_location).Lock();
|
|
||||||
use_inst->DecrementRemainingUses();
|
|
||||||
DEBUG_ASSERT(LocInfo(new_location).IsScratch());
|
|
||||||
return new_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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue