prepare for a change I'm about to make
[oota-llvm.git] / lib / CodeGen / PrologEpilogInserter.cpp
index aabf78bd338775528b5ebd7961bdb5f3fa3277ae..5a18b920fc9b3ce29bbe119e3635c1f9847b1535 100644 (file)
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Support/Compiler.h"
+#include <climits>
 using namespace llvm;
 
 namespace {
-  struct PEI : public MachineFunctionPass {
+  struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass {
     const char *getPassName() const {
       return "Prolog/Epilog Insertion & Frame Finalization";
     }
@@ -36,14 +38,24 @@ namespace {
     /// frame indexes with appropriate references.
     ///
     bool runOnMachineFunction(MachineFunction &Fn) {
-      // Scan the function for modified caller saved registers and insert spill
-      // code for any caller saved registers that are modified.  Also calculate
+      // Get MachineDebugInfo so that we can track the construction of the
+      // frame.
+      if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
+        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.
-      calculateCallerSavedRegisters(Fn);
+      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.
@@ -54,7 +66,7 @@ namespace {
 
       // 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
+      // called functions.  Because of this, calculateCalleeSavedRegisters
       // must be called before this function in order to set the HasCalls
       // and MaxCallFrameSize variables.
       insertPrologEpilogCode(Fn);
@@ -64,17 +76,16 @@ namespace {
       //
       replaceFrameIndices(Fn);
 
-      RegsToSave.clear();
-      StackSlots.clear();
       return true;
     }
-
+  
   private:
-    std::vector<std::pair<unsigned, const TargetRegisterClass*> > RegsToSave;
-    std::vector<int> StackSlots;
+    // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee save
+    // stack frame indexes.
+    unsigned MinCSFrameIndex, MaxCSFrameIndex;
 
-    void calculateCallerSavedRegisters(MachineFunction &Fn);
-    void saveCallerSavedRegisters(MachineFunction &Fn);
+    void calculateCalleeSavedRegisters(MachineFunction &Fn);
+    void saveCalleeSavedRegisters(MachineFunction &Fn);
     void calculateFrameObjectOffsets(MachineFunction &Fn);
     void replaceFrameIndices(MachineFunction &Fn);
     void insertPrologEpilogCode(MachineFunction &Fn);
@@ -88,15 +99,14 @@ namespace {
 FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
 
 
-/// calculateCallerSavedRegisters - 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.
 ///
-void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
+void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
   const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
   const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
-  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
 
   // Get the callee saved register list...
   const unsigned *CSRegs = RegInfo->getCalleeSaveRegs();
@@ -138,24 +148,25 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
   const bool *PhysRegsUsed = Fn.getUsedPhysregs();
   const TargetRegisterClass* const *CSRegClasses =
     RegInfo->getCalleeSaveRegClasses();
+  std::vector<CalleeSavedInfo> CSI;
   for (unsigned i = 0; CSRegs[i]; ++i) {
     unsigned Reg = CSRegs[i];
     if (PhysRegsUsed[Reg]) {
         // If the reg is modified, save it!
-      RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i]));
+      CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i]));
     } else {
       for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
            *AliasSet; ++AliasSet) {  // Check alias registers too.
         if (PhysRegsUsed[*AliasSet]) {
-          RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i]));
+          CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i]));
           break;
         }
       }
     }
   }
 
-  if (RegsToSave.empty())
-    return;   // Early exit if no caller saved registers are modified!
+  if (CSI.empty())
+    return;   // Early exit if no callee saved registers are modified!
 
   unsigned NumFixedSpillSlots;
   const std::pair<unsigned,int> *FixedSpillSlots =
@@ -163,9 +174,11 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
 
   // Now that we know which registers need to be saved and restored, allocate
   // stack slots for them.
-  for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
-    unsigned Reg = RegsToSave[i].first;
-    const TargetRegisterClass *RC = RegsToSave[i].second;
+  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();
 
     // Check to see if this physreg must be spilled to a particular stack slot
     // on this target.
@@ -177,21 +190,34 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
     int FrameIdx;
     if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) {
       // Nope, just spill it anywhere convenient.
-      FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment());
+      unsigned Align = RC->getAlignment();
+      unsigned StackAlign = TFI->getStackAlignment();
+      // We may not be able to sastify the desired alignment specification of
+      // the TargetRegisterClass if the stack alignment is smaller. Use the min.
+      Align = std::min(Align, StackAlign);
+      FrameIdx = FFI->CreateStackObject(RC->getSize(), Align);
+      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);
     }
-    StackSlots.push_back(FrameIdx);
+    CSI[i].setFrameIdx(FrameIdx);
   }
+
+  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) {
-  // Early exit if no caller saved registers are modified!
-  if (RegsToSave.empty())
+void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) {
+  // Get callee saved register information.
+  MachineFrameInfo *FFI = Fn.getFrameInfo();
+  const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+  
+  // Early exit if no callee saved registers are modified!
+  if (CSI.empty())
     return;
 
   const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
@@ -200,10 +226,10 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
   // code into the entry block.
   MachineBasicBlock *MBB = Fn.begin();
   MachineBasicBlock::iterator I = MBB->begin();
-  for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
+  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
     // Insert the spill to the stack frame.
-    RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i].first, StackSlots[i],
-                                 RegsToSave[i].second);
+    RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), CSI[i].getFrameIdx(),
+                                 CSI[i].getRegClass());
   }
 
   // Add code to restore the callee-save registers in each exiting block.
@@ -227,9 +253,10 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
       
       // Restore all registers immediately before the return and any terminators
       // that preceed it.
-      for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
-        RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i].first,
-                                      StackSlots[i], RegsToSave[i].second);
+      for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+        RegInfo->loadRegFromStackSlot(*MBB, I, CSI[i].getReg(),
+                                      CSI[i].getFrameIdx(),
+                                      CSI[i].getRegClass());
         assert(I != MBB->begin() &&
                "loadRegFromStackSlot didn't insert any code!");
         // Insert in reverse order.  loadRegFromStackSlot can insert multiple
@@ -289,7 +316,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)
@@ -310,6 +379,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.
@@ -326,8 +396,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) {