aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h27
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp7
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp13
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp13
-rw-r--r--lib/Target/X86/X86RegisterInfo.h4
-rw-r--r--test/CodeGen/X86/2004-02-13-FrameReturnAddress.ll2
-rw-r--r--test/CodeGen/X86/2008-08-31-EH_RETURN32.ll2
-rw-r--r--test/CodeGen/X86/2008-08-31-EH_RETURN64.ll2
8 files changed, 52 insertions, 18 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 91e8f80fd1..29f96e961a 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -567,18 +567,29 @@ public:
/// has variable sized allocas or if frame pointer elimination is disabled.
virtual bool hasFP(const MachineFunction &MF) const = 0;
- // hasReservedCallFrame - Under normal circumstances, when a frame pointer is
- // not required, we reserve argument space for call sites in the function
- // immediately on entry to the current function. This eliminates the need for
- // add/sub sp brackets around call sites. Returns true if the call frame is
- // included as part of the stack frame.
+ /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ /// not required, we reserve argument space for call sites in the function
+ /// immediately on entry to the current function. This eliminates the need for
+ /// add/sub sp brackets around call sites. Returns true if the call frame is
+ /// included as part of the stack frame.
virtual bool hasReservedCallFrame(MachineFunction &MF) const {
return !hasFP(MF);
}
- // needsStackRealignment - true if storage within the function requires the
- // stack pointer to be aligned more than the normal calling convention calls
- // for.
+ /// hasReservedSpillSlot - Return true if target has reserved a spill slot in
+ /// the stack frame of the given function for the specified register. e.g. On
+ /// x86, if the frame register is required, the first fixed stack object is
+ /// reserved as its spill slot. This tells PEI not to create a new stack frame
+ /// object for the given register. It should be called only after
+ /// processFunctionBeforeCalleeSavedScan().
+ virtual bool hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
+ int &FrameIdx) const {
+ return false;
+ }
+
+ /// needsStackRealignment - true if storage within the function requires the
+ /// stack pointer to be aligned more than the normal calling convention calls
+ /// for.
virtual bool needsStackRealignment(const MachineFunction &MF) const {
return false;
}
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 6582fd8c8d..2365316261 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -210,6 +210,12 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
unsigned Reg = I->getReg();
const TargetRegisterClass *RC = I->getRegClass();
+ int FrameIdx;
+ if (RegInfo->hasReservedSpillSlot(Fn, Reg, FrameIdx)) {
+ I->setFrameIdx(FrameIdx);
+ continue;
+ }
+
// Check to see if this physreg must be spilled to a particular stack slot
// on this target.
const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots;
@@ -217,7 +223,6 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
FixedSlot->first != Reg)
++FixedSlot;
- int FrameIdx;
if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
// Nope, just spill it anywhere convenient.
unsigned Align = RC->getAlignment();
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 5507e43b6d..c2cd04c896 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -2029,6 +2029,7 @@ bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
unsigned SlotSize = is64Bit ? 8 : 4;
MachineFunction &MF = *MBB.getParent();
+ unsigned FPReg = RI.getFrameRegister(MF);
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
unsigned CalleeFrameSize = 0;
@@ -2038,10 +2039,12 @@ bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
const TargetRegisterClass *RegClass = CSI[i-1].getRegClass();
// Add the callee-saved register as live-in. It's killed at the spill.
MBB.addLiveIn(Reg);
+ if (Reg == FPReg)
+ // X86RegisterInfo::emitPrologue will handle spilling of frame register.
+ continue;
if (RegClass != &X86::VR128RegClass) {
CalleeFrameSize += SlotSize;
- BuildMI(MBB, MI, DL, get(Opc))
- .addReg(Reg, RegState::Kill);
+ BuildMI(MBB, MI, DL, get(Opc)).addReg(Reg, RegState::Kill);
} else {
storeRegToStackSlot(MBB, MI, Reg, true, CSI[i-1].getFrameIdx(), RegClass);
}
@@ -2060,11 +2063,15 @@ bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
+ MachineFunction &MF = *MBB.getParent();
+ unsigned FPReg = RI.getFrameRegister(MF);
bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
-
unsigned Opc = is64Bit ? X86::POP64r : X86::POP32r;
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
+ if (Reg == FPReg)
+ // X86RegisterInfo::emitEpilogue will handle restoring of frame register.
+ continue;
const TargetRegisterClass *RegClass = CSI[i].getRegClass();
if (RegClass != &X86::VR128RegClass) {
BuildMI(MBB, MI, DL, get(Opc), Reg);
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 5b43d21d8e..be4764e276 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -345,6 +345,16 @@ bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
return !MF.getFrameInfo()->hasVarSizedObjects();
}
+bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
+ int &FrameIdx) const {
+ if (Reg == FramePtr && hasFP(MF)) {
+ FrameIdx = MF.getFrameInfo()->getObjectIndexBegin();
+ return true;
+ }
+ return false;
+}
+
+
int
X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
int Offset = MF.getFrameInfo()->getObjectOffset(FI) + SlotSize;
@@ -493,10 +503,7 @@ X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
calculateMaxStackAlignment(FFI));
FFI->setMaxAlignment(MaxAlign);
-}
-void
-X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
if (TailCallReturnAddrDelta < 0) {
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index e1a23cb4ed..eac8426a98 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -125,6 +125,9 @@ public:
bool hasReservedCallFrame(MachineFunction &MF) const;
+ bool hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
+ int &FrameIdx) const;
+
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
@@ -132,7 +135,6 @@ public:
void eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, RegScavenger *RS = NULL) const;
- void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
diff --git a/test/CodeGen/X86/2004-02-13-FrameReturnAddress.ll b/test/CodeGen/X86/2004-02-13-FrameReturnAddress.ll
index f48b1d3adf..ee3169af04 100644
--- a/test/CodeGen/X86/2004-02-13-FrameReturnAddress.ll
+++ b/test/CodeGen/X86/2004-02-13-FrameReturnAddress.ll
@@ -1,4 +1,6 @@
; RUN: llvm-as < %s | llc -march=x86 | grep {(%esp}
+; RUN: llvm-as < %s | llc -march=x86 | grep {pushl %ebp} | count 1
+; RUN: llvm-as < %s | llc -march=x86 | grep {popl %ebp} | count 1
declare i8* @llvm.returnaddress(i32)
diff --git a/test/CodeGen/X86/2008-08-31-EH_RETURN32.ll b/test/CodeGen/X86/2008-08-31-EH_RETURN32.ll
index e22b647a13..8aa330e7b1 100644
--- a/test/CodeGen/X86/2008-08-31-EH_RETURN32.ll
+++ b/test/CodeGen/X86/2008-08-31-EH_RETURN32.ll
@@ -1,5 +1,5 @@
; Check that eh_return & unwind_init were properly lowered
-; RUN: llvm-as < %s | llc | grep %ebp | count 9
+; RUN: llvm-as < %s | llc | grep %ebp | count 7
; RUN: llvm-as < %s | llc | grep %ecx | count 5
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
diff --git a/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll b/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll
index 7d01824400..80eeba7e1e 100644
--- a/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll
+++ b/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll
@@ -1,5 +1,5 @@
; Check that eh_return & unwind_init were properly lowered
-; RUN: llvm-as < %s | llc | grep %rbp | count 7
+; RUN: llvm-as < %s | llc | grep %rbp | count 5
; RUN: llvm-as < %s | llc | grep %rcx | count 3
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"