aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/LocalStackSlotAllocation.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-08-19 23:52:25 +0000
committerJim Grosbach <grosbach@apple.com>2010-08-19 23:52:25 +0000
commite2f556933e1a19cddf6d4f370e2770c0f763b025 (patch)
tree5dd6b09fab81ed02643c883b33e9e06c2acceaa3 /lib/CodeGen/LocalStackSlotAllocation.cpp
parentb08ceb8135daf015dc38f9d9048cb075215da383 (diff)
Better handling of offsets on frame index references. rdar://8277890
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LocalStackSlotAllocation.cpp')
-rw-r--r--lib/CodeGen/LocalStackSlotAllocation.cpp28
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/CodeGen/LocalStackSlotAllocation.cpp b/lib/CodeGen/LocalStackSlotAllocation.cpp
index a4a43875ce..01a1af1be6 100644
--- a/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -182,7 +182,7 @@ lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
// 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 (TRI->isBaseRegInRange(MI, RegOffset.first, Offset))
+ if (TRI->isFrameOffsetLegal(MI, Offset))
return true;
}
return false;
@@ -225,6 +225,7 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
// an object allocated in the local block.
if (MI->getOperand(i).isFI()) {
int FrameIdx = MI->getOperand(i).getIndex();
+
// Don't try this with values not in the local block.
if (!MFI->isObjectPreAllocated(FrameIdx))
continue;
@@ -232,13 +233,15 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
DEBUG(dbgs() << "Considering: " << *MI);
if (TRI->needsFrameBaseReg(MI, i)) {
unsigned BaseReg = 0;
- unsigned Offset = 0;
+ int64_t Offset = 0;
DEBUG(dbgs() << " Replacing FI in: " << *MI);
// If we have a suitable base register available, use it; otherwise
- // create a new one.
-
+ // create a new one. Note that any offset encoded in the
+ // instruction itself will be taken into account by the target,
+ // so we don't have to adjust for it here when reusing a base
+ // register.
std::pair<unsigned, int64_t> RegOffset;
if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
LocalOffsets[FrameIdx], MI, TRI)) {
@@ -250,15 +253,26 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
} else {
// No previously defined register was in range, so create a
// new one.
+ int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, i);
const TargetRegisterClass *RC = TRI->getPointerRegClass();
BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
+ DEBUG(dbgs() << " Materializing base register " << BaseReg <<
+ " at frame local offset " <<
+ LocalOffsets[FrameIdx] + InstrOffset << "\n");
// Tell the target to insert the instruction to initialize
// the base register.
- TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+ TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx,
+ InstrOffset);
+
+ // The base register already includes any offset specified
+ // by the instruction, so account for that so it doesn't get
+ // applied twice.
+ Offset = -InstrOffset;
- BaseRegisters.push_back(std::pair<unsigned, int64_t>(BaseReg,
- Offset));
+ BaseRegisters.push_back(
+ std::pair<unsigned, int64_t>(BaseReg,
+ LocalOffsets[FrameIdx] + InstrOffset));
++NumBaseRegisters;
}
assert(BaseReg != 0 && "Unable to allocate virtual base register!");