summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LocalStackSlotAllocation.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-08-23 20:40:38 +0000
committerJim Grosbach <grosbach@apple.com>2010-08-23 20:40:38 +0000
commit67ff81a08319f916571cea90ed92e17015c8584f (patch)
tree67ac334f7b7b359e113a753663da398d7bb6a1e1 /lib/CodeGen/LocalStackSlotAllocation.cpp
parent11bc1652c9447d85204dc6f7c878b9c95e668a96 (diff)
downloadllvm-67ff81a08319f916571cea90ed92e17015c8584f.tar.gz
llvm-67ff81a08319f916571cea90ed92e17015c8584f.tar.bz2
llvm-67ff81a08319f916571cea90ed92e17015c8584f.tar.xz
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
Diffstat (limited to 'lib/CodeGen/LocalStackSlotAllocation.cpp')
-rw-r--r--lib/CodeGen/LocalStackSlotAllocation.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/lib/CodeGen/LocalStackSlotAllocation.cpp b/lib/CodeGen/LocalStackSlotAllocation.cpp
index 7e1e287367..811cb07628 100644
--- a/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -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;
}
-
}
}
}