From d31f55c2361068d71f988829d167ce9e24b8f813 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 28 Sep 2006 00:10:27 +0000 Subject: [PATCH] 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. llvm-svn: 30636 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 78 +++++++++++++++++++---- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 6a530e69e259..81d9724be42e 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -25,6 +25,7 @@ #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Compiler.h" +#include using namespace llvm; namespace { @@ -42,15 +43,19 @@ namespace { if (MachineDebugInfo *DI = getAnalysisToUpdate()) { 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 // code for any callee saved registers that are modified. Also calculate // the MaxCallFrameSize and HasCalls variables for the function's frame // information and eliminates call frame pseudo instructions. calculateCalleeSavedRegisters(Fn); - // Add the code to save and restore the caller saved registers - saveCallerSavedRegisters(Fn); + // Add the code to save and restore the callee saved registers + saveCalleeSavedRegisters(Fn); // Allow the target machine to make final modifications to the function // before the frame layout is finalized. @@ -75,8 +80,12 @@ namespace { } private: + // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee save + // stack frame indexes. + unsigned MinCSFrameIndex, MaxCSFrameIndex; + void calculateCalleeSavedRegisters(MachineFunction &Fn); - void saveCallerSavedRegisters(MachineFunction &Fn); + void saveCalleeSavedRegisters(MachineFunction &Fn); void calculateFrameObjectOffsets(MachineFunction &Fn); void replaceFrameIndices(MachineFunction &Fn); void insertPrologEpilogCode(MachineFunction &Fn); @@ -90,7 +99,7 @@ namespace { 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 /// the function's frame information and eliminates call frame pseudo /// instructions. @@ -157,7 +166,7 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { } 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; const std::pair *FixedSpillSlots = @@ -165,6 +174,8 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { // Now that we know which registers need to be saved and restored, allocate // stack slots for them. + MinCSFrameIndex = INT_MAX; + MaxCSFrameIndex = 0; for (unsigned i = 0, e = CSI.size(); i != e; ++i) { unsigned Reg = CSI[i].getReg(); const TargetRegisterClass *RC = CSI[i].getRegClass(); @@ -180,6 +191,8 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { // Nope, just spill it anywhere convenient. FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment()); + if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; + if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; } else { // Spill it to the stack where we must. FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); @@ -190,15 +203,15 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 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. /// -void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { +void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { // Get callee saved register information. MachineFrameInfo *FFI = Fn.getFrameInfo(); const std::vector &CSI = FFI->getCalleeSavedInfo(); - // Early exit if no caller saved registers are modified! + // Early exit if no callee saved registers are modified! if (CSI.empty()) return; @@ -298,7 +311,49 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 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) { + if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) + continue; + // If stack grows down, we need to add size of find the lowest // address of the object. 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 // function. This ensures that any calls to subroutines have their stack // frames suitable aligned. @@ -335,8 +391,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { } -/// insertPrologEpilogCode - Scan the function for modified caller saved -/// registers, insert spill code for these caller saved registers, then add +/// insertPrologEpilogCode - Scan the function for modified callee saved +/// registers, insert spill code for these callee saved registers, then add /// prolog and epilog code to the function. /// void PEI::insertPrologEpilogCode(MachineFunction &Fn) {