mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 21:57:55 +00:00
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:
parent
02569d7355
commit
c2b4ec37de
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user