mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-11 06:06:52 +00:00
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
This commit is contained in:
parent
f95a1068bd
commit
315fbb6aea
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user