Skip to content
Snippets Groups Projects
Commit 14a1c184 authored by Krzysztof Parzyszek's avatar Krzysztof Parzyszek
Browse files

When looking for a spill slot in reg scavenger, find one that matches RC

When looking for an available spill slot, the register scavenger would stop
after finding the first one with no register assigned to it. That slot may
have size and alignment that do not meet the requirements of the register
that is to be spilled. Instead, find an available slot that is the closest
in size and alignment to one that is needed to spill a register from RC.

Differential Revision: http://reviews.llvm.org/D20295

llvm-svn: 269969
parent 08ce7347
No related branches found
No related tags found
No related merge requests found
...@@ -392,11 +392,35 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, ...@@ -392,11 +392,35 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
return SReg; return SReg;
} }
// Find an available scavenging slot. // Find an available scavenging slot with size and alignment matching
unsigned SI; // the requirements of the class RC.
for (SI = 0; SI < Scavenged.size(); ++SI) MachineFunction &MF = *I->getParent()->getParent();
if (Scavenged[SI].Reg == 0) MachineFrameInfo &MFI = *MF.getFrameInfo();
break; unsigned NeedSize = RC->getSize();
unsigned NeedAlign = RC->getAlignment();
unsigned SI = Scavenged.size(), Diff = UINT_MAX;
for (unsigned I = 0; I < Scavenged.size(); ++I) {
if (Scavenged[I].Reg != 0)
continue;
// Verify that this slot is valid for this register.
int FI = Scavenged[I].FrameIndex;
unsigned S = MFI.getObjectSize(FI);
unsigned A = MFI.getObjectAlignment(FI);
if (NeedSize > S || NeedAlign > A)
continue;
// Avoid wasting slots with large size and/or large alignment. Pick one
// that is the best fit for this register class (in street metric).
// Picking a larger slot than necessary could happen if a slot for a
// larger register is reserved before a slot for a smaller one. When
// trying to spill a smaller register, the large slot would be found
// first, thus making it impossible to spill the larger register later.
unsigned D = (S-NeedSize) + (A-NeedAlign);
if (D < Diff) {
SI = I;
Diff = D;
}
}
if (SI == Scavenged.size()) { if (SI == Scavenged.size()) {
// We need to scavenge a register but have no spill slot, the target // We need to scavenge a register but have no spill slot, the target
...@@ -411,8 +435,15 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, ...@@ -411,8 +435,15 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
// otherwise, use the emergency stack spill slot. // otherwise, use the emergency stack spill slot.
if (!TRI->saveScavengerRegister(*MBB, I, UseMI, RC, SReg)) { if (!TRI->saveScavengerRegister(*MBB, I, UseMI, RC, SReg)) {
// Spill the scavenged register before I. // Spill the scavenged register before I.
assert(Scavenged[SI].FrameIndex >= 0 && if (Scavenged[SI].FrameIndex < 0) {
"Cannot scavenge register without an emergency spill slot!"); Twine Msg = Twine("Error while trying to spill ") + TRI->getName(SReg) +
" from class " + TRI->getRegClassName(RC) +
": Cannot scavenge register without an emergency spill slot!";
// Keep both error functions, since llvm_unreachable prints the call
// stack, but it does not terminate program in release mode.
llvm_unreachable(Msg.str().c_str());
report_fatal_error(Msg);
}
TII->storeRegToStackSlot(*MBB, I, SReg, true, Scavenged[SI].FrameIndex, TII->storeRegToStackSlot(*MBB, I, SReg, true, Scavenged[SI].FrameIndex,
RC, TRI); RC, TRI);
MachineBasicBlock::iterator II = std::prev(I); MachineBasicBlock::iterator II = std::prev(I);
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment