Split saveCallerSavedRegisters into two methods for clarity, and add comments.

Add support for targets that must spill certain physregs at certain locations.

Patch contributed by Nate Begeman, slightly hacked by me.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15701 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2004-08-12 19:01:14 +00:00
parent 28690ea285
commit c330b68fb7

View File

@ -40,6 +40,9 @@ namespace {
// code for any caller saved registers that are modified. Also calculate
// the MaxCallFrameSize and HasCalls variables for the function's frame
// information and eliminates call frame pseudo instructions.
calculateCallerSavedRegisters(Fn);
// Add the code to save and restore the caller saved registers
saveCallerSavedRegisters(Fn);
// Allow the target machine to make final modifications to the function
@ -49,17 +52,28 @@ namespace {
// Calculate actual frame offsets for all of the abstract stack objects...
calculateFrameObjectOffsets(Fn);
// Add prolog and epilog code to the function.
// Add prolog and epilog code to the function. This function is required
// to align the stack frame as necessary for any stack variables or
// called functions. Because of this, calculateCallerSavedRegisters
// must be called before this function in order to set the HasCalls
// and MaxCallFrameSize variables.
insertPrologEpilogCode(Fn);
// Replace all MO_FrameIndex operands with physical register references
// and actual offsets.
//
replaceFrameIndices(Fn);
RegsToSave.clear();
StackSlots.clear();
return true;
}
private:
std::vector<unsigned> RegsToSave;
std::vector<int> StackSlots;
void calculateCallerSavedRegisters(MachineFunction &Fn);
void saveCallerSavedRegisters(MachineFunction &Fn);
void calculateFrameObjectOffsets(MachineFunction &Fn);
void replaceFrameIndices(MachineFunction &Fn);
@ -74,15 +88,14 @@ namespace {
FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
/// saveCallerSavedRegisters - Scan the function for modified caller saved
/// registers and insert spill code for any caller saved registers that are
/// modified. Also calculate the MaxCallFrameSize and HasCalls variables for
/// calculateCallerSavedRegisters - Scan the function for modified caller saved
/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for
/// the function's frame information and eliminates call frame pseudo
/// instructions.
///
void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
const TargetFrameInfo &FrameInfo = *Fn.getTarget().getFrameInfo();
const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
// Get the callee saved register list...
const unsigned *CSRegs = RegInfo->getCalleeSaveRegs();
@ -131,7 +144,6 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
// Now figure out which *callee saved* registers are modified by the current
// function, thus needing to be saved and restored in the prolog/epilog.
//
std::vector<unsigned> RegsToSave;
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
if (ModifiedRegs[Reg]) {
@ -150,13 +162,44 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
if (RegsToSave.empty())
return; // Early exit if no caller saved registers are modified!
unsigned NumFixedSpillSlots;
std::pair<unsigned,int> *FixedSpillSlots =
TFI->getCalleeSaveSpillSlots(NumFixedSpillSlots);
// Now that we know which registers need to be saved and restored, allocate
// stack slots for them.
std::vector<int> StackSlots;
for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
int FrameIdx = FFI->CreateStackObject(RegInfo->getRegClass(RegsToSave[i]));
unsigned Reg = RegsToSave[i];
int FrameIdx;
const TargetRegisterClass *RC = RegInfo->getRegClass(Reg);
// Check to see if this physreg must be spilled to a particular stack slot
// on this target.
std::pair<unsigned,int> *FixedSlot = FixedSpillSlots;
while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots &&
FixedSlot->first != Reg)
++FixedSlot;
if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) {
// Nope, just spill it anywhere convenient.
FrameIdx = FFI->CreateStackObject(RC);
} else {
// Spill it to the stack where we must.
FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second);
}
StackSlots.push_back(FrameIdx);
}
}
/// saveCallerSavedRegisters - Insert spill code for any caller saved registers
/// that are modified in the function.
///
void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
// Early exit if no caller saved registers are modified!
if (RegsToSave.empty())
return;
const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
// Now that we have a stack slot for each register to be saved, insert spill
// code into the entry block...