summaryrefslogtreecommitdiff
path: root/lib/CodeGen/PrologEpilogInserter.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-08-12 19:01:14 +0000
committerChris Lattner <sabre@nondot.org>2004-08-12 19:01:14 +0000
commitc330b68fb7f1cb7f05a60ab4d811bba397538840 (patch)
tree29f2e501f537f3fa73093442b49652b056d802a9 /lib/CodeGen/PrologEpilogInserter.cpp
parent28690ea28515f60550ea4256a98b9e1b2caef563 (diff)
downloadllvm-c330b68fb7f1cb7f05a60ab4d811bba397538840.tar.gz
llvm-c330b68fb7f1cb7f05a60ab4d811bba397538840.tar.bz2
llvm-c330b68fb7f1cb7f05a60ab4d811bba397538840.tar.xz
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
Diffstat (limited to 'lib/CodeGen/PrologEpilogInserter.cpp')
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp61
1 files changed, 52 insertions, 9 deletions
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index b698170ceb..a12b6ca33d 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -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...