aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMRegisterInfo.cpp
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@gmail.com>2007-05-07 23:15:16 +0000
committerLauro Ramos Venancio <lauro.venancio@gmail.com>2007-05-07 23:15:16 +0000
commit356e72c4f1a90b0ff306838e8841b9b550460cd9 (patch)
tree2d0d97952bc1cd1267e1f6c84e6444d4281420a2 /lib/Target/ARM/ARMRegisterInfo.cpp
parentfd4dbf78aed3a15e2537bf5701ddb1b063d2ed74 (diff)
Fix PR1390 in a better way.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36916 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMRegisterInfo.cpp')
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.cpp53
1 files changed, 41 insertions, 12 deletions
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp
index d562f162b7..266f1b0567 100644
--- a/lib/Target/ARM/ARMRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -1055,8 +1055,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
if (!STI.isTargetDarwin()) {
if (Reg == ARM::LR)
LRSpilled = true;
- else
- CS1Spilled = true;
+ CS1Spilled = true;
continue;
}
@@ -1131,6 +1130,33 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
NumGPRSpills++;
}
+ // If stack and double are 8-byte aligned and we are spilling an odd number
+ // of GPRs. Spill one extra callee save GPR so we won't have to pad between
+ // the integer and double callee save areas.
+ unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
+ if (TargetAlign == 8 && (NumGPRSpills & 1)) {
+ if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
+ for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
+ unsigned Reg = UnspilledCS1GPRs[i];
+ // Don't spiil high register if the function is thumb
+ if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) {
+ MF.setPhysRegUsed(Reg);
+ AFI->setCSRegisterIsSpilled(Reg);
+ if (!isReservedReg(MF, Reg))
+ ExtraCSSpill = true;
+ break;
+ }
+ }
+ } else if (!UnspilledCS2GPRs.empty() &&
+ !AFI->isThumbFunction()) {
+ unsigned Reg = UnspilledCS2GPRs.front();
+ MF.setPhysRegUsed(Reg);
+ AFI->setCSRegisterIsSpilled(Reg);
+ if (!isReservedReg(MF, Reg))
+ ExtraCSSpill = true;
+ }
+ }
+
// Estimate if we might need to scavenge a register at some point in order
// to materialize a stack offset. If so, either spill one additiona
// callee-saved register or reserve a special spill slot to facilitate
@@ -1160,26 +1186,29 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
if (Size >= Limit) {
// If any non-reserved CS register isn't spilled, just spill one or two
// extra. That should take care of it!
- unsigned Extra;
- while (!ExtraCSSpill && !UnspilledCS1GPRs.empty()) {
+ unsigned NumExtras = TargetAlign / 4;
+ SmallVector<unsigned, 2> Extras;
+ while (NumExtras && !UnspilledCS1GPRs.empty()) {
unsigned Reg = UnspilledCS1GPRs.back();
UnspilledCS1GPRs.pop_back();
if (!isReservedReg(MF, Reg)) {
- Extra = Reg;
- ExtraCSSpill = true;
+ Extras.push_back(Reg);
+ NumExtras--;
}
}
- while (!ExtraCSSpill && !UnspilledCS2GPRs.empty()) {
+ while (NumExtras && !UnspilledCS2GPRs.empty()) {
unsigned Reg = UnspilledCS2GPRs.back();
UnspilledCS2GPRs.pop_back();
if (!isReservedReg(MF, Reg)) {
- Extra = Reg;
- ExtraCSSpill = true;
+ Extras.push_back(Reg);
+ NumExtras--;
}
}
- if (ExtraCSSpill) {
- MF.setPhysRegUsed(Extra);
- AFI->setCSRegisterIsSpilled(Extra);
+ if (Extras.size() && NumExtras == 0) {
+ for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
+ MF.setPhysRegUsed(Extras[i]);
+ AFI->setCSRegisterIsSpilled(Extras[i]);
+ }
} else {
// Reserve a slot closest to SP or frame pointer.
const TargetRegisterClass *RC = &ARM::GPRRegClass;