PEI now place callee save spills closest to the address pointed to by the

incoming stack. This allows X86 backend to use push / pop in epilogue /
prologue.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30636 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-09-28 00:10:27 +00:00
parent 02569d7355
commit c2b4ec37de

View File

@ -25,6 +25,7 @@
#include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include <climits>
using namespace llvm; using namespace llvm;
namespace { namespace {
@ -42,15 +43,19 @@ namespace {
if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) { if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
Fn.getFrameInfo()->setMachineDebugInfo(DI); Fn.getFrameInfo()->setMachineDebugInfo(DI);
} }
// Allow the target machine to make some adjustments to the function
// e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
Fn.getTarget().getRegisterInfo()->processFunctionBeforeCalleeSaveScan(Fn);
// Scan the function for modified callee saved registers and insert spill // Scan the function for modified callee saved registers and insert spill
// code for any callee saved registers that are modified. Also calculate // code for any callee saved registers that are modified. Also calculate
// the MaxCallFrameSize and HasCalls variables for the function's frame // the MaxCallFrameSize and HasCalls variables for the function's frame
// information and eliminates call frame pseudo instructions. // information and eliminates call frame pseudo instructions.
calculateCalleeSavedRegisters(Fn); calculateCalleeSavedRegisters(Fn);
// Add the code to save and restore the caller saved registers // Add the code to save and restore the callee saved registers
saveCallerSavedRegisters(Fn); saveCalleeSavedRegisters(Fn);
// Allow the target machine to make final modifications to the function // Allow the target machine to make final modifications to the function
// before the frame layout is finalized. // before the frame layout is finalized.
@ -75,8 +80,12 @@ namespace {
} }
private: private:
// MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee save
// stack frame indexes.
unsigned MinCSFrameIndex, MaxCSFrameIndex;
void calculateCalleeSavedRegisters(MachineFunction &Fn); void calculateCalleeSavedRegisters(MachineFunction &Fn);
void saveCallerSavedRegisters(MachineFunction &Fn); void saveCalleeSavedRegisters(MachineFunction &Fn);
void calculateFrameObjectOffsets(MachineFunction &Fn); void calculateFrameObjectOffsets(MachineFunction &Fn);
void replaceFrameIndices(MachineFunction &Fn); void replaceFrameIndices(MachineFunction &Fn);
void insertPrologEpilogCode(MachineFunction &Fn); void insertPrologEpilogCode(MachineFunction &Fn);
@ -90,7 +99,7 @@ namespace {
FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
/// calculateCalleeSavedRegisters - Scan the function for modified caller saved /// calculateCalleeSavedRegisters - Scan the function for modified callee saved
/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for /// registers. Also calculate the MaxCallFrameSize and HasCalls variables for
/// the function's frame information and eliminates call frame pseudo /// the function's frame information and eliminates call frame pseudo
/// instructions. /// instructions.
@ -157,7 +166,7 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
} }
if (CSI.empty()) if (CSI.empty())
return; // Early exit if no caller saved registers are modified! return; // Early exit if no callee saved registers are modified!
unsigned NumFixedSpillSlots; unsigned NumFixedSpillSlots;
const std::pair<unsigned,int> *FixedSpillSlots = const std::pair<unsigned,int> *FixedSpillSlots =
@ -165,6 +174,8 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
// Now that we know which registers need to be saved and restored, allocate // Now that we know which registers need to be saved and restored, allocate
// stack slots for them. // stack slots for them.
MinCSFrameIndex = INT_MAX;
MaxCSFrameIndex = 0;
for (unsigned i = 0, e = CSI.size(); i != e; ++i) { for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg(); unsigned Reg = CSI[i].getReg();
const TargetRegisterClass *RC = CSI[i].getRegClass(); const TargetRegisterClass *RC = CSI[i].getRegClass();
@ -180,6 +191,8 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) {
// Nope, just spill it anywhere convenient. // Nope, just spill it anywhere convenient.
FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment()); FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment());
if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
} else { } else {
// Spill it to the stack where we must. // Spill it to the stack where we must.
FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second);
@ -190,15 +203,15 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
FFI->setCalleeSavedInfo(CSI); FFI->setCalleeSavedInfo(CSI);
} }
/// saveCallerSavedRegisters - Insert spill code for any caller saved registers /// saveCalleeSavedRegisters - Insert spill code for any callee saved registers
/// that are modified in the function. /// that are modified in the function.
/// ///
void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) {
// Get callee saved register information. // Get callee saved register information.
MachineFrameInfo *FFI = Fn.getFrameInfo(); MachineFrameInfo *FFI = Fn.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
// Early exit if no caller saved registers are modified! // Early exit if no callee saved registers are modified!
if (CSI.empty()) if (CSI.empty())
return; return;
@ -298,7 +311,49 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
if (FixedOff > Offset) Offset = FixedOff; if (FixedOff > Offset) Offset = FixedOff;
} }
// First assign frame offsets to stack objects that are used to spill
// callee save registers.
if (StackGrowsDown) {
for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
if (i < MinCSFrameIndex || i > MaxCSFrameIndex)
continue;
// If stack grows down, we need to add size of find the lowest
// address of the object.
Offset += FFI->getObjectSize(i);
unsigned Align = FFI->getObjectAlignment(i);
// If the alignment of this object is greater than that of the stack, then
// increase the stack alignment to match.
MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
FFI->setObjectOffset(i, -Offset); // Set the computed offset
}
} else {
for (int i = FFI->getObjectIndexEnd()-1; i >= 0; --i) {
if ((unsigned)i < MinCSFrameIndex || (unsigned)i > MaxCSFrameIndex)
continue;
unsigned Align = FFI->getObjectAlignment(i);
// If the alignment of this object is greater than that of the stack, then
// increase the stack alignment to match.
MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
FFI->setObjectOffset(i, Offset);
Offset += FFI->getObjectSize(i);
}
}
// Then assign frame offsets to stack objects that are not used to spill
// callee save registers.
for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
continue;
// If stack grows down, we need to add size of find the lowest // If stack grows down, we need to add size of find the lowest
// address of the object. // address of the object.
if (StackGrowsDown) if (StackGrowsDown)
@ -319,6 +374,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
} }
} }
// Align the final stack pointer offset, but only if there are calls in the // Align the final stack pointer offset, but only if there are calls in the
// function. This ensures that any calls to subroutines have their stack // function. This ensures that any calls to subroutines have their stack
// frames suitable aligned. // frames suitable aligned.
@ -335,8 +391,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
} }
/// insertPrologEpilogCode - Scan the function for modified caller saved /// insertPrologEpilogCode - Scan the function for modified callee saved
/// registers, insert spill code for these caller saved registers, then add /// registers, insert spill code for these callee saved registers, then add
/// prolog and epilog code to the function. /// prolog and epilog code to the function.
/// ///
void PEI::insertPrologEpilogCode(MachineFunction &Fn) { void PEI::insertPrologEpilogCode(MachineFunction &Fn) {