diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-05-18 18:16:00 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-05-18 18:16:00 +0000 |
commit | 14a1c18448cb626889743e04e5ffd2613bf74f9a (patch) | |
tree | 935705af0ec38e7a5aef080358b33389c29f3b79 /llvm/lib/CodeGen/RegisterScavenging.cpp | |
parent | 08ce73470c2fb45b78e35c15423bb840cb114b46 (diff) | |
download | bcm5719-llvm-14a1c18448cb626889743e04e5ffd2613bf74f9a.tar.gz bcm5719-llvm-14a1c18448cb626889743e04e5ffd2613bf74f9a.zip |
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
Diffstat (limited to 'llvm/lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r-- | llvm/lib/CodeGen/RegisterScavenging.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp index 8e002749d3b..b7836b4146c 100644 --- a/llvm/lib/CodeGen/RegisterScavenging.cpp +++ b/llvm/lib/CodeGen/RegisterScavenging.cpp @@ -392,11 +392,35 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, return SReg; } - // Find an available scavenging slot. - unsigned SI; - for (SI = 0; SI < Scavenged.size(); ++SI) - if (Scavenged[SI].Reg == 0) - break; + // Find an available scavenging slot with size and alignment matching + // the requirements of the class RC. + MachineFunction &MF = *I->getParent()->getParent(); + MachineFrameInfo &MFI = *MF.getFrameInfo(); + 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()) { // We need to scavenge a register but have no spill slot, the target @@ -411,8 +435,15 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, // otherwise, use the emergency stack spill slot. if (!TRI->saveScavengerRegister(*MBB, I, UseMI, RC, SReg)) { // Spill the scavenged register before I. - assert(Scavenged[SI].FrameIndex >= 0 && - "Cannot scavenge register without an emergency spill slot!"); + if (Scavenged[SI].FrameIndex < 0) { + 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, RC, TRI); MachineBasicBlock::iterator II = std::prev(I); |