mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-26 07:34:06 +00:00
Create a stack frame on ARM when
- Function uses all scratch registers AND - Function does not use any callee saved registers AND - Stack size is too big to address with immediate offsets. In this case a register must be scavenged to calculate the address of a stack object, and the scavenger needs a spare register or emergency spill slot. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97071 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9792de7363
commit
657baec0af
@ -513,7 +513,7 @@ cannotEliminateFrame(const MachineFunction &MF) const {
|
||||
}
|
||||
|
||||
/// estimateStackSize - Estimate and return the size of the frame.
|
||||
static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
|
||||
static unsigned estimateStackSize(MachineFunction &MF) {
|
||||
const MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||
int Offset = 0;
|
||||
for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
|
||||
@ -671,8 +671,16 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
}
|
||||
}
|
||||
|
||||
// If any of the stack slot references may be out of range of an immediate
|
||||
// offset, make sure a register (or a spill slot) is available for the
|
||||
// register scavenger. Note that if we're indexing off the frame pointer, the
|
||||
// effective stack size is 4 bytes larger since the FP points to the stack
|
||||
// slot of the previous FP.
|
||||
bool BigStack = RS &&
|
||||
estimateStackSize(MF) + (hasFP(MF) ? 4 : 0) >= estimateRSStackSizeLimit(MF);
|
||||
|
||||
bool ExtraCSSpill = false;
|
||||
if (!CanEliminateFrame || cannotEliminateFrame(MF)) {
|
||||
if (BigStack || !CanEliminateFrame || cannotEliminateFrame(MF)) {
|
||||
AFI->setHasStackFrame(true);
|
||||
|
||||
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
|
||||
@ -727,51 +735,43 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
// callee-saved register or reserve a special spill slot to facilitate
|
||||
// register scavenging. Thumb1 needs a spill slot for stack pointer
|
||||
// adjustments also, even when the frame itself is small.
|
||||
if (RS && !ExtraCSSpill) {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
// If any of the stack slot references may be out of range of an
|
||||
// immediate offset, make sure a register (or a spill slot) is
|
||||
// available for the register scavenger. Note that if we're indexing
|
||||
// off the frame pointer, the effective stack size is 4 bytes larger
|
||||
// since the FP points to the stack slot of the previous FP.
|
||||
if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
|
||||
>= estimateRSStackSizeLimit(MF)) {
|
||||
// If any non-reserved CS register isn't spilled, just spill one or two
|
||||
// extra. That should take care of it!
|
||||
unsigned NumExtras = TargetAlign / 4;
|
||||
SmallVector<unsigned, 2> Extras;
|
||||
while (NumExtras && !UnspilledCS1GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS1GPRs.back();
|
||||
UnspilledCS1GPRs.pop_back();
|
||||
if (BigStack && !ExtraCSSpill) {
|
||||
// If any non-reserved CS register isn't spilled, just spill one or two
|
||||
// extra. That should take care of it!
|
||||
unsigned NumExtras = TargetAlign / 4;
|
||||
SmallVector<unsigned, 2> Extras;
|
||||
while (NumExtras && !UnspilledCS1GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS1GPRs.back();
|
||||
UnspilledCS1GPRs.pop_back();
|
||||
if (!isReservedReg(MF, Reg)) {
|
||||
Extras.push_back(Reg);
|
||||
NumExtras--;
|
||||
}
|
||||
}
|
||||
// For non-Thumb1 functions, also check for hi-reg CS registers
|
||||
if (!AFI->isThumb1OnlyFunction()) {
|
||||
while (NumExtras && !UnspilledCS2GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS2GPRs.back();
|
||||
UnspilledCS2GPRs.pop_back();
|
||||
if (!isReservedReg(MF, Reg)) {
|
||||
Extras.push_back(Reg);
|
||||
NumExtras--;
|
||||
}
|
||||
}
|
||||
// For non-Thumb1 functions, also check for hi-reg CS registers
|
||||
if (!AFI->isThumb1OnlyFunction()) {
|
||||
while (NumExtras && !UnspilledCS2GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS2GPRs.back();
|
||||
UnspilledCS2GPRs.pop_back();
|
||||
if (!isReservedReg(MF, Reg)) {
|
||||
Extras.push_back(Reg);
|
||||
NumExtras--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Extras.size() && NumExtras == 0) {
|
||||
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
||||
MF.getRegInfo().setPhysRegUsed(Extras[i]);
|
||||
AFI->setCSRegisterIsSpilled(Extras[i]);
|
||||
}
|
||||
} else if (!AFI->isThumb1OnlyFunction()) {
|
||||
// note: Thumb1 functions spill to R12, not the stack.
|
||||
// Reserve a slot closest to SP or frame pointer.
|
||||
const TargetRegisterClass *RC = ARM::GPRRegisterClass;
|
||||
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
|
||||
RC->getAlignment(),
|
||||
false));
|
||||
}
|
||||
if (Extras.size() && NumExtras == 0) {
|
||||
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
||||
MF.getRegInfo().setPhysRegUsed(Extras[i]);
|
||||
AFI->setCSRegisterIsSpilled(Extras[i]);
|
||||
}
|
||||
} else if (!AFI->isThumb1OnlyFunction()) {
|
||||
// note: Thumb1 functions spill to R12, not the stack. Reserve a slot
|
||||
// closest to SP or frame pointer.
|
||||
const TargetRegisterClass *RC = ARM::GPRRegisterClass;
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
|
||||
RC->getAlignment(),
|
||||
false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
test/CodeGen/Thumb2/2010-02-24-BigStack.ll
Normal file
15
test/CodeGen/Thumb2/2010-02-24-BigStack.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llc < %s -O0 -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 -mattr=+vfp2
|
||||
; This test creates a big stack frame without spilling any callee-saved registers.
|
||||
; Make sure the whole stack frame is addrerssable wiothout scavenger crashes.
|
||||
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
|
||||
target triple = "thumbv7-apple-darwin3.0.0-iphoneos"
|
||||
|
||||
define arm_apcscc void @FindMin(double* %panelTDEL, i8* %dclOfRow, i32 %numRows, i32 %numCols, double* %retMin_RES_TDEL) {
|
||||
entry:
|
||||
%panelTDEL.addr = alloca double*, align 4 ; <double**> [#uses=1]
|
||||
%panelResTDEL = alloca [2560 x double], align 4 ; <[2560 x double]*> [#uses=0]
|
||||
store double* %panelTDEL, double** %panelTDEL.addr
|
||||
store double* %retMin_RES_TDEL, double** undef
|
||||
store i32 0, i32* undef
|
||||
unreachable
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user