ARMFrameLowering: Only set ExtraCSSpill for actually unused registers.
The code assumed that unclobbered/unspilled callee saved registers are unused in the function. This is not true for callee saved registers that are also used to pass parameters such as swiftself. rdar://33401922 llvm-svn: 309350
This commit is contained in:
parent
fe33551051
commit
c618a466f1
|
@ -1743,7 +1743,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
(MFI.adjustsStack() && !canSimplifyCallFramePseudos(MF)) ||
|
||||
// For large argument stacks fp relative addressed may overflow.
|
||||
(HasFP && (MaxFixedOffset - MaxFPOffset) >= (int)EstimatedRSStackSizeLimit);
|
||||
bool ExtraCSSpill = false;
|
||||
if (BigFrameOffsets ||
|
||||
!CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
|
||||
AFI->setHasStackFrame(true);
|
||||
|
@ -1768,6 +1767,10 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
CS1Spilled = true;
|
||||
}
|
||||
|
||||
// This is true when we inserted a spill for an unused register that can now
|
||||
// be used for register scavenging.
|
||||
bool ExtraCSSpill = false;
|
||||
|
||||
if (AFI->isThumb1OnlyFunction()) {
|
||||
// For Thumb1-only targets, we need some low registers when we save and
|
||||
// restore the high registers (which aren't allocatable, but could be
|
||||
|
@ -1870,7 +1873,9 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
SavedRegs.set(Reg);
|
||||
NumGPRSpills++;
|
||||
CS1Spilled = true;
|
||||
ExtraCSSpill = true;
|
||||
assert(!MRI.isReserved(Reg) && "Should not be reserved");
|
||||
if (!MRI.isPhysRegUsed(Reg))
|
||||
ExtraCSSpill = true;
|
||||
UnspilledCS1GPRs.erase(llvm::find(UnspilledCS1GPRs, Reg));
|
||||
if (Reg == ARM::LR)
|
||||
LRSpilled = true;
|
||||
|
@ -1889,7 +1894,8 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
UnspilledCS1GPRs.erase(LRPos);
|
||||
|
||||
ForceLRSpill = false;
|
||||
ExtraCSSpill = true;
|
||||
if (!MRI.isReserved(ARM::LR) && !MRI.isPhysRegUsed(ARM::LR))
|
||||
ExtraCSSpill = true;
|
||||
}
|
||||
|
||||
// If stack and double are 8-byte aligned and we are spilling an odd number
|
||||
|
@ -1909,7 +1915,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
SavedRegs.set(Reg);
|
||||
DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI)
|
||||
<< " to make up alignment\n");
|
||||
if (!MRI.isReserved(Reg))
|
||||
if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg))
|
||||
ExtraCSSpill = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1919,7 +1925,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
SavedRegs.set(Reg);
|
||||
DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI)
|
||||
<< " to make up alignment\n");
|
||||
if (!MRI.isReserved(Reg))
|
||||
if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg))
|
||||
ExtraCSSpill = true;
|
||||
}
|
||||
}
|
||||
|
@ -1955,11 +1961,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (Extras.size() && NumExtras == 0) {
|
||||
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
||||
SavedRegs.set(Extras[i]);
|
||||
if (NumExtras == 0) {
|
||||
for (unsigned Reg : Extras) {
|
||||
SavedRegs.set(Reg);
|
||||
if (!MRI.isPhysRegUsed(Reg))
|
||||
ExtraCSSpill = true;
|
||||
}
|
||||
} else if (!AFI->isThumb1OnlyFunction()) {
|
||||
}
|
||||
if (!ExtraCSSpill && !AFI->isThumb1OnlyFunction()) {
|
||||
// note: Thumb1 functions spill to R12, not the stack. Reserve a slot
|
||||
// closest to SP or frame pointer.
|
||||
assert(RS && "Register scavenging not provided");
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# RUN: llc -o - %s -mtriple=arm-- -run-pass prologepilog | FileCheck %s
|
||||
--- |
|
||||
define swiftcc i8* @need_emergency_slot(i8 *swiftself %v) {
|
||||
; Just a dummy to add a swiftself bit. The real code is in the MI below.
|
||||
unreachable
|
||||
}
|
||||
...
|
||||
---
|
||||
# CHECK-LABEL: name: need_emergency_slot
|
||||
# Make sure we do not just assume an unsaved/restored callee saved register
|
||||
# is free to use. Callee saved parameters may still be used if they were used
|
||||
# to pass arguments (as in swiftself).
|
||||
name: need_emergency_slot
|
||||
tracksRegLiveness: true
|
||||
stack:
|
||||
- { id: 0, type: default, size: 8, alignment: 8 }
|
||||
- { id: 1, type: default, size: 4096, alignment: 8 }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %r10 ; swiftself parameter comes in as %r10
|
||||
|
||||
; Bring up register pressure to force emergency spilling, coax scavenging
|
||||
; to use %r10 as that one is not spilled/restored.
|
||||
%r0 = IMPLICIT_DEF
|
||||
%r1 = IMPLICIT_DEF
|
||||
%r2 = IMPLICIT_DEF
|
||||
%r3 = IMPLICIT_DEF
|
||||
%r4 = IMPLICIT_DEF
|
||||
%r5 = IMPLICIT_DEF
|
||||
%r6 = IMPLICIT_DEF
|
||||
%r7 = IMPLICIT_DEF
|
||||
%r8 = IMPLICIT_DEF
|
||||
%r9 = IMPLICIT_DEF
|
||||
%r11 = IMPLICIT_DEF
|
||||
%r12 = IMPLICIT_DEF
|
||||
%lr = IMPLICIT_DEF
|
||||
|
||||
; Computing the large stack offset requires an extra register. We should
|
||||
; not just use %r10 for that.
|
||||
; CHECK-NOT: STRi12 %1,{{.*}}%r10
|
||||
|
||||
STRi12 %r1, %stack.0, 0, 14, _ :: (store 4)
|
||||
|
||||
; use the swiftself parameter value.
|
||||
KILL %r10
|
||||
|
||||
KILL %r0
|
||||
KILL %r1
|
||||
KILL %r2
|
||||
KILL %r3
|
||||
KILL %r4
|
||||
KILL %r5
|
||||
KILL %r6
|
||||
KILL %r7
|
||||
KILL %r8
|
||||
KILL %r9
|
||||
KILL %r11
|
||||
KILL %r12
|
||||
KILL %lr
|
||||
...
|
Loading…
Reference in New Issue