Tidy up.
[oota-llvm.git] / lib / CodeGen / PrologEpilogInserter.cpp
index 1e9704eb3fbcd3c60f7d1ed492db755589c1972a..05052d354df7acf8cd45f70d33e0e1e2f0e09087 100644 (file)
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Support/Visibility.h"
 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,6 +37,12 @@ namespace {
     /// frame indexes with appropriate references.
     ///
     bool runOnMachineFunction(MachineFunction &Fn) {
+      // Get MachineDebugInfo so that we can track the construction of the
+      // frame.
+      if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
+        Fn.getFrameInfo()->setMachineDebugInfo(DI);
+      }
+      
       // 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 the function's frame
@@ -64,15 +71,10 @@ namespace {
       //
       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);
@@ -96,7 +98,6 @@ FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
 void PEI::calculateCallerSavedRegisters(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();
@@ -136,22 +137,26 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
   // function, thus needing to be saved and restored in the prolog/epilog.
   //
   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]) {
-      RegsToSave.push_back(Reg);  // If the reg is modified, save it!
+        // If the reg is modified, save it!
+      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(Reg);
+          CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i]));
           break;
         }
       }
     }
   }
 
-  if (RegsToSave.empty())
+  if (CSI.empty())
     return;   // Early exit if no caller saved registers are modified!
 
   unsigned NumFixedSpillSlots;
@@ -160,8 +165,9 @@ 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];
+  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.
@@ -173,23 +179,27 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) {
     int FrameIdx;
     if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) {
       // Nope, just spill it anywhere convenient.
-      FrameIdx = FFI->CreateStackObject(RegInfo->getSpillSize(Reg)/8,
-                                        RegInfo->getSpillAlignment(Reg)/8);
+      FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment());
     } else {
       // Spill it to the stack where we must.
-      FrameIdx = FFI->CreateFixedObject(RegInfo->getSpillSize(Reg)/8,
-                                        FixedSlot->second);
+      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
 /// that are modified in the function.
 ///
 void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
+  // Get callee saved register information.
+  MachineFrameInfo *FFI = Fn.getFrameInfo();
+  const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+  
   // Early exit if no caller saved registers are modified!
-  if (RegsToSave.empty())
+  if (CSI.empty())
     return;
 
   const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
@@ -198,10 +208,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], StackSlots[i],
-                                 0 /*FIXME*/);
+    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.
@@ -225,9 +235,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], StackSlots[i],
-                                      0 /*FIXME*/);
+      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
@@ -256,6 +267,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
   MachineFrameInfo *FFI = Fn.getFrameInfo();
 
   unsigned StackAlignment = TFI.getStackAlignment();
+  unsigned MaxAlign = 0;
 
   // Start at the beginning of the local area.
   // The Offset is the distance from the stack top in the direction
@@ -293,9 +305,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
       Offset += FFI->getObjectSize(i);
 
     unsigned Align = FFI->getObjectAlignment(i);
-    assert(Align <= StackAlignment && "Cannot align stack object to higher "
-           "alignment boundary than the stack itself!");
-    Offset = (Offset+Align-1)/Align*Align;   // Adjust to Alignment boundary...
+    // 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;
 
     if (StackGrowsDown) {
       FFI->setObjectOffset(i, -Offset);        // Set the computed offset
@@ -313,6 +327,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
 
   // Set the final value of the stack pointer...
   FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea());
+
+  // Remember the required stack alignment in case targets need it to perform
+  // dynamic stack alignment.
+  assert(FFI->getMaxAlignment() == MaxAlign &&
+         "Stack alignment calculation broken!");
 }