summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-08-05 19:27:37 +0000
committerJim Grosbach <grosbach@apple.com>2010-08-05 19:27:37 +0000
commite3ede5e2e4de6d028956c0b75c6bfa17ec50cc09 (patch)
treeb8ecbda30d7ad8a353e31ad0267e8015a1bb935f
parent751aaf8ac586860df8f22c3707905d1a8005f1ba (diff)
downloadllvm-e3ede5e2e4de6d028956c0b75c6bfa17ec50cc09.tar.gz
llvm-e3ede5e2e4de6d028956c0b75c6bfa17ec50cc09.tar.bz2
llvm-e3ede5e2e4de6d028956c0b75c6bfa17ec50cc09.tar.xz
For local variables in functions with a frame pointer, use FP as a base
register for local access when it's closer to the stack slot being refererenced than the stack pointer. Make sure to take into account any argument frame SP adjustments that are in affect at the time. rdar://8256090 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110366 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp55
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h2
2 files changed, 39 insertions, 18 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index d3251dc76f..32baf5a1b3 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -980,48 +980,70 @@ ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return ARM::SP;
}
+// Provide a base+offset reference to an FI slot for debug info. It's the
+// same as what we use for resolving the code-gen references for now.
+// FIXME: This can go wrong when references are SP-relative and simple call
+// frames aren't used.
int
ARMBaseRegisterInfo::getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const {
+ return ResolveFrameIndexReference(MF, FI, FrameReg, 0);
+}
+
+int
+ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF,
+ int FI,
+ unsigned &FrameReg,
+ int SPAdj) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
+ int FPOffset = Offset - AFI->getFramePtrSpillOffset();
bool isFixed = MFI->isFixedObjectIndex(FI);
FrameReg = ARM::SP;
+ Offset += SPAdj;
if (AFI->isGPRCalleeSavedArea1Frame(FI))
- Offset -= AFI->getGPRCalleeSavedArea1Offset();
+ return Offset - AFI->getGPRCalleeSavedArea1Offset();
else if (AFI->isGPRCalleeSavedArea2Frame(FI))
- Offset -= AFI->getGPRCalleeSavedArea2Offset();
+ return Offset - AFI->getGPRCalleeSavedArea2Offset();
else if (AFI->isDPRCalleeSavedAreaFrame(FI))
- Offset -= AFI->getDPRCalleeSavedAreaOffset();
- else if (needsStackRealignment(MF)) {
- // When dynamically realigning the stack, use the frame pointer for
- // parameters, and the stack pointer for locals.
+ return Offset - AFI->getDPRCalleeSavedAreaOffset();
+
+ // When dynamically realigning the stack, use the frame pointer for
+ // parameters, and the stack pointer for locals.
+ if (needsStackRealignment(MF)) {
assert (hasFP(MF) && "dynamic stack realignment without a FP!");
if (isFixed) {
FrameReg = getFrameRegister(MF);
- Offset -= AFI->getFramePtrSpillOffset();
+ Offset = FPOffset;
}
- } else if (hasFP(MF) && AFI->hasStackFrame()) {
+ return Offset;
+ }
+
+ // If there is a frame pointer, use it when we can.
+ if (hasFP(MF) && AFI->hasStackFrame()) {
+ // Use frame pointer to reference fixed objects. Use it for locals if
+ // there are VLAs (and thus the SP isn't reliable as a base).
if (isFixed || MFI->hasVarSizedObjects()) {
- // Use frame pointer to reference fixed objects unless this is a
- // frameless function.
FrameReg = getFrameRegister(MF);
- Offset -= AFI->getFramePtrSpillOffset();
+ Offset = FPOffset;
} else if (AFI->isThumb2Function()) {
- // In Thumb2 mode, the negative offset is very limited.
- int FPOffset = Offset - AFI->getFramePtrSpillOffset();
+ // In Thumb2 mode, the negative offset is very limited. Try to avoid
+ // out of range references.
if (FPOffset >= -255 && FPOffset < 0) {
FrameReg = getFrameRegister(MF);
Offset = FPOffset;
}
+ } else if (Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
+ // Otherwise, use SP or FP, whichever is closer to the stack slot.
+ FrameReg = getFrameRegister(MF);
+ Offset = FPOffset;
}
}
return Offset;
}
-
int
ARMBaseRegisterInfo::getFrameIndexOffset(const MachineFunction &MF,
int FI) const {
@@ -1357,10 +1379,7 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int FrameIndex = MI.getOperand(i).getIndex();
unsigned FrameReg;
- int Offset = getFrameIndexReference(MF, FrameIndex, FrameReg);
- if (FrameReg != ARM::SP)
- SPAdj = 0;
- Offset += SPAdj;
+ int Offset = ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);
// Special handling of dbg_value instructions.
if (MI.isDebugValue()) {
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index eefbc12692..d644ecc1ab 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -116,6 +116,8 @@ public:
unsigned getFrameRegister(const MachineFunction &MF) const;
int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const;
+ int ResolveFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg, int SPAdj) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
// Exception handling queries.