Better handling of local offsets for downwards growing stacks. This corrects

relative offsets when there are offsets encoded in the instructions and
simplifies final allocation in PEI. rdar://8277890

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111836 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-08-23 20:40:38 +00:00
parent 11bc1652c9
commit 67ff81a083
2 changed files with 39 additions and 25 deletions

View File

@ -46,7 +46,7 @@ namespace {
SmallVector<int64_t,16> LocalOffsets;
void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset,
unsigned &MaxAlign);
bool StackGrowsDown, unsigned &MaxAlign);
void calculateFrameObjectOffsets(MachineFunction &Fn);
bool insertFrameReferenceRegisters(MachineFunction &Fn);
public:
@ -102,7 +102,12 @@ bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
int FrameIdx, int64_t &Offset,
bool StackGrowsDown,
unsigned &MaxAlign) {
// If the stack grows down, add the object size to find the lowest address.
if (StackGrowsDown)
Offset += MFI->getObjectSize(FrameIdx);
unsigned Align = MFI->getObjectAlignment(FrameIdx);
// If the alignment of this object is greater than that of the stack, then
@ -112,13 +117,16 @@ void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
// Adjust to alignment boundary.
Offset = (Offset + Align - 1) / Align * Align;
int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;
DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset "
<< Offset << "\n");
<< LocalOffset << "\n");
// Keep the offset available for base register allocation
LocalOffsets[FrameIdx] = Offset;
LocalOffsets[FrameIdx] = LocalOffset;
// And tell MFI about it for PEI to use later
MFI->mapLocalFrameObject(FrameIdx, Offset);
Offset += MFI->getObjectSize(FrameIdx);
MFI->mapLocalFrameObject(FrameIdx, LocalOffset);
if (!StackGrowsDown)
Offset += MFI->getObjectSize(FrameIdx);
++NumAllocations;
}
@ -129,6 +137,9 @@ void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Loop over all of the stack objects, assigning sequential addresses...
MachineFrameInfo *MFI = Fn.getFrameInfo();
const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo();
bool StackGrowsDown =
TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
int64_t Offset = 0;
unsigned MaxAlign = 0;
@ -136,7 +147,8 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
// stack.
SmallSet<int, 16> LargeStackObjs;
if (MFI->getStackProtectorIndex() >= 0) {
AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, MaxAlign);
AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset,
StackGrowsDown, MaxAlign);
// Assign large stack objects first.
for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
@ -147,7 +159,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
if (!MFI->MayNeedStackProtector(i))
continue;
AdjustStackOffset(MFI, i, Offset, MaxAlign);
AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
LargeStackObjs.insert(i);
}
}
@ -162,7 +174,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
if (LargeStackObjs.count(i))
continue;
AdjustStackOffset(MFI, i, Offset, MaxAlign);
AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
}
// Remember how big this blob of stack space is
@ -173,8 +185,8 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
static inline bool
lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
std::pair<unsigned, int64_t> &RegOffset,
int64_t FrameSizeAdjust,
int64_t LocalFrameOffset,
bool StackGrowsDown,
const MachineInstr *MI,
const TargetRegisterInfo *TRI) {
unsigned e = Regs.size();
@ -182,9 +194,7 @@ lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
RegOffset = Regs[i];
// Check if the relative offset from the where the base register references
// to the target address is in range for the instruction.
int64_t Offset = LocalFrameOffset - RegOffset.second;
if (StackGrowsDown)
Offset = -Offset;
int64_t Offset = FrameSizeAdjust + LocalFrameOffset - RegOffset.second;
if (TRI->isFrameOffsetLegal(MI, Offset))
return true;
}
@ -241,6 +251,8 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
if (TRI->needsFrameBaseReg(MI, i)) {
unsigned BaseReg = 0;
int64_t Offset = 0;
int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize()
: 0;
DEBUG(dbgs() << " Replacing FI in: " << *MI);
@ -251,15 +263,15 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
// register.
std::pair<unsigned, int64_t> RegOffset;
if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
FrameSizeAdjust,
LocalOffsets[FrameIdx],
StackGrowsDown, MI, TRI)) {
MI, TRI)) {
DEBUG(dbgs() << " Reusing base register " <<
RegOffset.first << "\n");
// We found a register to reuse.
BaseReg = RegOffset.first;
Offset = LocalOffsets[FrameIdx] - RegOffset.second;
if (StackGrowsDown)
Offset = -Offset;
Offset = FrameSizeAdjust + LocalOffsets[FrameIdx] -
RegOffset.second;
} else {
// No previously defined register was in range, so create a
// new one.
@ -280,9 +292,10 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
// applied twice.
Offset = -InstrOffset;
int64_t BaseOffset = FrameSizeAdjust + LocalOffsets[FrameIdx] +
InstrOffset;
BaseRegisters.push_back(
std::pair<unsigned, int64_t>(BaseReg,
LocalOffsets[FrameIdx] + InstrOffset));
std::pair<unsigned, int64_t>(BaseReg, BaseOffset));
++NumBaseRegisters;
UsedBaseReg = true;
}
@ -295,7 +308,6 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
++NumReplacements;
}
}
}
}

View File

@ -572,16 +572,18 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
// Allocate the local block
Offset += MFI->getLocalFrameSize();
// Resolve offsets for objects in the local block.
for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
int64_t FIOffset = MFI->getLocalFrameBaseOffset() + Entry.second;
AdjustStackOffset(MFI, Entry.first, StackGrowsDown, FIOffset, MaxAlign);
int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
FIOffset << "]\n");
MFI->setObjectOffset(Entry.first, FIOffset);
}
// Allocate the local block
Offset += MFI->getLocalFrameSize();
MaxAlign = std::max(Align, MaxAlign);
}
// Make sure that the stack protector comes before the local variables on the