summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMFrameLowering.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-07-05 16:05:50 +0000
committerJim Grosbach <grosbach@apple.com>2011-07-05 16:05:50 +0000
commitea53901dc974aaa7a62b8be73fbefb38878d16b3 (patch)
treee8bd1a05f0783d7e24844da229b420138a41abe6 /llvm/lib/Target/ARM/ARMFrameLowering.cpp
parentbf3eec68dd01d4f9b219c9be764e34cd1f8b4cf9 (diff)
downloadbcm5719-llvm-ea53901dc974aaa7a62b8be73fbefb38878d16b3.tar.gz
bcm5719-llvm-ea53901dc974aaa7a62b8be73fbefb38878d16b3.zip
ARM estimateStackSize() needs to account for simplified call frames.
If the function allocates reserved stack space for callee argument frames, estimateStackSize() needs to account for that, as it doesn't show up as ordinary frame objects. Otherwise, a callee with a large argument list will throw off the calculations for whether to allocate an emergency spill slot and we get assert() failures in the register scavenger. rdar://9715469 llvm-svn: 134415
Diffstat (limited to 'llvm/lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 9e943e44c9e..381b404519e 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -739,20 +739,52 @@ static unsigned GetFunctionSizeInBytes(const MachineFunction &MF,
/// estimateStackSize - Estimate and return the size of the frame.
/// FIXME: Make generic?
static unsigned estimateStackSize(MachineFunction &MF) {
- const MachineFrameInfo *FFI = MF.getFrameInfo();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
+ const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
+ unsigned MaxAlign = MFI->getMaxAlignment();
int Offset = 0;
- for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
- int FixedOff = -FFI->getObjectOffset(i);
+
+ // This code is very, very similar to PEI::calculateFrameObjectOffsets().
+ // It really should be refactored to share code. Until then, changes
+ // should keep in mind that there's tight coupling between the two.
+
+ for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
+ int FixedOff = -MFI->getObjectOffset(i);
if (FixedOff > Offset) Offset = FixedOff;
}
- for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
- if (FFI->isDeadObjectIndex(i))
+ for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
+ if (MFI->isDeadObjectIndex(i))
continue;
- Offset += FFI->getObjectSize(i);
- unsigned Align = FFI->getObjectAlignment(i);
+ Offset += MFI->getObjectSize(i);
+ unsigned Align = MFI->getObjectAlignment(i);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
+
+ MaxAlign = std::max(Align, MaxAlign);
}
+
+ if (MFI->adjustsStack() && TFI->hasReservedCallFrame(MF))
+ Offset += MFI->getMaxCallFrameSize();
+
+ // Round up the size to a multiple of the alignment. If the function has
+ // any calls or alloca's, align to the target's StackAlignment value to
+ // ensure that the callee's frame or the alloca data is suitably aligned;
+ // otherwise, for leaf functions, align to the TransientStackAlignment
+ // value.
+ unsigned StackAlign;
+ if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
+ (RegInfo->needsStackRealignment(MF) && MFI->getObjectIndexEnd() != 0))
+ StackAlign = TFI->getStackAlignment();
+ else
+ StackAlign = TFI->getTransientStackAlignment();
+
+ // If the frame pointer is eliminated, all frame offsets will be relative to
+ // SP not FP. Align to MaxAlign so this works.
+ StackAlign = std::max(StackAlign, MaxAlign);
+ unsigned AlignMask = StackAlign - 1;
+ Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
+
return (unsigned)Offset;
}
OpenPOWER on IntegriCloud