mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-26 05:25:47 +00:00
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:
@@ -46,7 +46,7 @@ namespace {
|
|||||||
SmallVector<int64_t,16> LocalOffsets;
|
SmallVector<int64_t,16> LocalOffsets;
|
||||||
|
|
||||||
void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset,
|
void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset,
|
||||||
unsigned &MaxAlign);
|
bool StackGrowsDown, unsigned &MaxAlign);
|
||||||
void calculateFrameObjectOffsets(MachineFunction &Fn);
|
void calculateFrameObjectOffsets(MachineFunction &Fn);
|
||||||
bool insertFrameReferenceRegisters(MachineFunction &Fn);
|
bool insertFrameReferenceRegisters(MachineFunction &Fn);
|
||||||
public:
|
public:
|
||||||
@@ -102,7 +102,12 @@ bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
|
/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
|
||||||
void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
|
void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
|
||||||
int FrameIdx, int64_t &Offset,
|
int FrameIdx, int64_t &Offset,
|
||||||
|
bool StackGrowsDown,
|
||||||
unsigned &MaxAlign) {
|
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);
|
unsigned Align = MFI->getObjectAlignment(FrameIdx);
|
||||||
|
|
||||||
// If the alignment of this object is greater than that of the stack, then
|
// 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.
|
// Adjust to alignment boundary.
|
||||||
Offset = (Offset + Align - 1) / Align * Align;
|
Offset = (Offset + Align - 1) / Align * Align;
|
||||||
|
|
||||||
|
int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;
|
||||||
DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset "
|
DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset "
|
||||||
<< Offset << "\n");
|
<< LocalOffset << "\n");
|
||||||
// Keep the offset available for base register allocation
|
// Keep the offset available for base register allocation
|
||||||
LocalOffsets[FrameIdx] = Offset;
|
LocalOffsets[FrameIdx] = LocalOffset;
|
||||||
// And tell MFI about it for PEI to use later
|
// And tell MFI about it for PEI to use later
|
||||||
MFI->mapLocalFrameObject(FrameIdx, Offset);
|
MFI->mapLocalFrameObject(FrameIdx, LocalOffset);
|
||||||
Offset += MFI->getObjectSize(FrameIdx);
|
|
||||||
|
if (!StackGrowsDown)
|
||||||
|
Offset += MFI->getObjectSize(FrameIdx);
|
||||||
|
|
||||||
++NumAllocations;
|
++NumAllocations;
|
||||||
}
|
}
|
||||||
@@ -129,6 +137,9 @@ void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
|
|||||||
void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
||||||
// Loop over all of the stack objects, assigning sequential addresses...
|
// Loop over all of the stack objects, assigning sequential addresses...
|
||||||
MachineFrameInfo *MFI = Fn.getFrameInfo();
|
MachineFrameInfo *MFI = Fn.getFrameInfo();
|
||||||
|
const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo();
|
||||||
|
bool StackGrowsDown =
|
||||||
|
TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
|
||||||
int64_t Offset = 0;
|
int64_t Offset = 0;
|
||||||
unsigned MaxAlign = 0;
|
unsigned MaxAlign = 0;
|
||||||
|
|
||||||
@@ -136,7 +147,8 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
|||||||
// stack.
|
// stack.
|
||||||
SmallSet<int, 16> LargeStackObjs;
|
SmallSet<int, 16> LargeStackObjs;
|
||||||
if (MFI->getStackProtectorIndex() >= 0) {
|
if (MFI->getStackProtectorIndex() >= 0) {
|
||||||
AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, MaxAlign);
|
AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset,
|
||||||
|
StackGrowsDown, MaxAlign);
|
||||||
|
|
||||||
// Assign large stack objects first.
|
// Assign large stack objects first.
|
||||||
for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
|
for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
|
||||||
@@ -147,7 +159,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
|||||||
if (!MFI->MayNeedStackProtector(i))
|
if (!MFI->MayNeedStackProtector(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AdjustStackOffset(MFI, i, Offset, MaxAlign);
|
AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
|
||||||
LargeStackObjs.insert(i);
|
LargeStackObjs.insert(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +174,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
|||||||
if (LargeStackObjs.count(i))
|
if (LargeStackObjs.count(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AdjustStackOffset(MFI, i, Offset, MaxAlign);
|
AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember how big this blob of stack space is
|
// Remember how big this blob of stack space is
|
||||||
@@ -173,8 +185,8 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
|||||||
static inline bool
|
static inline bool
|
||||||
lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
|
lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
|
||||||
std::pair<unsigned, int64_t> &RegOffset,
|
std::pair<unsigned, int64_t> &RegOffset,
|
||||||
|
int64_t FrameSizeAdjust,
|
||||||
int64_t LocalFrameOffset,
|
int64_t LocalFrameOffset,
|
||||||
bool StackGrowsDown,
|
|
||||||
const MachineInstr *MI,
|
const MachineInstr *MI,
|
||||||
const TargetRegisterInfo *TRI) {
|
const TargetRegisterInfo *TRI) {
|
||||||
unsigned e = Regs.size();
|
unsigned e = Regs.size();
|
||||||
@@ -182,9 +194,7 @@ lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
|
|||||||
RegOffset = Regs[i];
|
RegOffset = Regs[i];
|
||||||
// Check if the relative offset from the where the base register references
|
// Check if the relative offset from the where the base register references
|
||||||
// to the target address is in range for the instruction.
|
// to the target address is in range for the instruction.
|
||||||
int64_t Offset = LocalFrameOffset - RegOffset.second;
|
int64_t Offset = FrameSizeAdjust + LocalFrameOffset - RegOffset.second;
|
||||||
if (StackGrowsDown)
|
|
||||||
Offset = -Offset;
|
|
||||||
if (TRI->isFrameOffsetLegal(MI, Offset))
|
if (TRI->isFrameOffsetLegal(MI, Offset))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -241,6 +251,8 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
|
|||||||
if (TRI->needsFrameBaseReg(MI, i)) {
|
if (TRI->needsFrameBaseReg(MI, i)) {
|
||||||
unsigned BaseReg = 0;
|
unsigned BaseReg = 0;
|
||||||
int64_t Offset = 0;
|
int64_t Offset = 0;
|
||||||
|
int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize()
|
||||||
|
: 0;
|
||||||
|
|
||||||
DEBUG(dbgs() << " Replacing FI in: " << *MI);
|
DEBUG(dbgs() << " Replacing FI in: " << *MI);
|
||||||
|
|
||||||
@@ -251,15 +263,15 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
|
|||||||
// register.
|
// register.
|
||||||
std::pair<unsigned, int64_t> RegOffset;
|
std::pair<unsigned, int64_t> RegOffset;
|
||||||
if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
|
if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
|
||||||
|
FrameSizeAdjust,
|
||||||
LocalOffsets[FrameIdx],
|
LocalOffsets[FrameIdx],
|
||||||
StackGrowsDown, MI, TRI)) {
|
MI, TRI)) {
|
||||||
DEBUG(dbgs() << " Reusing base register " <<
|
DEBUG(dbgs() << " Reusing base register " <<
|
||||||
RegOffset.first << "\n");
|
RegOffset.first << "\n");
|
||||||
// We found a register to reuse.
|
// We found a register to reuse.
|
||||||
BaseReg = RegOffset.first;
|
BaseReg = RegOffset.first;
|
||||||
Offset = LocalOffsets[FrameIdx] - RegOffset.second;
|
Offset = FrameSizeAdjust + LocalOffsets[FrameIdx] -
|
||||||
if (StackGrowsDown)
|
RegOffset.second;
|
||||||
Offset = -Offset;
|
|
||||||
} else {
|
} else {
|
||||||
// No previously defined register was in range, so create a
|
// No previously defined register was in range, so create a
|
||||||
// new one.
|
// new one.
|
||||||
@@ -280,9 +292,10 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
|
|||||||
// applied twice.
|
// applied twice.
|
||||||
Offset = -InstrOffset;
|
Offset = -InstrOffset;
|
||||||
|
|
||||||
|
int64_t BaseOffset = FrameSizeAdjust + LocalOffsets[FrameIdx] +
|
||||||
|
InstrOffset;
|
||||||
BaseRegisters.push_back(
|
BaseRegisters.push_back(
|
||||||
std::pair<unsigned, int64_t>(BaseReg,
|
std::pair<unsigned, int64_t>(BaseReg, BaseOffset));
|
||||||
LocalOffsets[FrameIdx] + InstrOffset));
|
|
||||||
++NumBaseRegisters;
|
++NumBaseRegisters;
|
||||||
UsedBaseReg = true;
|
UsedBaseReg = true;
|
||||||
}
|
}
|
||||||
@@ -295,7 +308,6 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
|
|||||||
|
|
||||||
++NumReplacements;
|
++NumReplacements;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -572,16 +572,18 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
|||||||
|
|
||||||
DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
|
DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
|
||||||
|
|
||||||
// Allocate the local block
|
|
||||||
Offset += MFI->getLocalFrameSize();
|
|
||||||
|
|
||||||
// Resolve offsets for objects in the local block.
|
// Resolve offsets for objects in the local block.
|
||||||
for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
|
for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
|
||||||
std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
|
std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
|
||||||
int64_t FIOffset = MFI->getLocalFrameBaseOffset() + Entry.second;
|
int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
|
||||||
|
DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
|
||||||
AdjustStackOffset(MFI, Entry.first, StackGrowsDown, FIOffset, MaxAlign);
|
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
|
// Make sure that the stack protector comes before the local variables on the
|
||||||
|
Reference in New Issue
Block a user