// 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
// 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);
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();
// 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]) {
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...