diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-08-23 20:40:38 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-08-23 20:40:38 +0000 |
commit | 67ff81a08319f916571cea90ed92e17015c8584f (patch) | |
tree | 67ac334f7b7b359e113a753663da398d7bb6a1e1 /lib/CodeGen/LocalStackSlotAllocation.cpp | |
parent | 11bc1652c9447d85204dc6f7c878b9c95e668a96 (diff) |
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.cpp | 50 |
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; } - } } } |