improve EH global handling, patch by Duncan Sands.
[oota-llvm.git] / lib / CodeGen / PrologEpilogInserter.cpp
index d056da964913617ef3d0146fc12d6dd2e296652a..478f3d3a5f2b6f578f419ad5a3e5f77e9671851d 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
@@ -38,16 +39,18 @@ namespace {
     /// frame indexes with appropriate references.
     ///
     bool runOnMachineFunction(MachineFunction &Fn) {
-      // Get MachineDebugInfo so that we can track the construction of the
+      const MRegisterInfo *MRI = Fn.getTarget().getRegisterInfo();
+      RS = MRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
+
+      // Get MachineModuleInfo so that we can track the construction of the
       // frame.
-      if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
-        Fn.getFrameInfo()->setMachineDebugInfo(DI);
+      if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>()) {
+        Fn.getFrameInfo()->setMachineModuleInfo(MMI);
       }
 
       // Allow the target machine to make some adjustments to the function
       // e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
-      Fn.getTarget().getRegisterInfo()
-        ->processFunctionBeforeCalleeSavedScan(Fn);
+      MRI->processFunctionBeforeCalleeSavedScan(Fn, RS);
 
       // Scan the function for modified callee saved registers and insert spill
       // code for any callee saved registers that are modified.  Also calculate
@@ -77,10 +80,13 @@ namespace {
       //
       replaceFrameIndices(Fn);
 
+      delete RS;
       return true;
     }
   
   private:
+    RegScavenger *RS;
+
     // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
     // stack frame indexes.
     unsigned MinCSFrameIndex, MaxCSFrameIndex;
@@ -150,19 +156,18 @@ void PEI::calculateCalleeSavedRegisters(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.
   //
-  const bool *PhysRegsUsed = Fn.getUsedPhysregs();
   const TargetRegisterClass* const *CSRegClasses =
     RegInfo->getCalleeSavedRegClasses();
   std::vector<CalleeSavedInfo> CSI;
   for (unsigned i = 0; CSRegs[i]; ++i) {
     unsigned Reg = CSRegs[i];
-    if (PhysRegsUsed[Reg]) {
+    if (Fn.isPhysRegUsed(Reg)) {
         // 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]) {
+        if (Fn.isPhysRegUsed(*AliasSet)) {
           CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i]));
           break;
         }
@@ -231,10 +236,12 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) {
   MachineBasicBlock::iterator I = MBB->begin();
   if (!RegInfo->spillCalleeSavedRegisters(*MBB, I, CSI)) {
     for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      // Add the callee-saved register as live-in. It's killed at the spill.
+      MBB->addLiveIn(CSI[i].getReg());
+
       // Insert the spill to the stack frame.
       RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(),
-                                   CSI[i].getFrameIdx(),
-                                   CSI[i].getRegClass());
+                                   CSI[i].getFrameIdx(), CSI[i].getRegClass());
     }
   }
 
@@ -292,13 +299,12 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
   // Loop over all of the stack objects, assigning sequential addresses...
   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
   // of stack growth -- so it's always positive.
-  int Offset = TFI.getOffsetOfLocalArea();
+  int64_t Offset = TFI.getOffsetOfLocalArea();
   if (StackGrowsDown)
     Offset = -Offset;
   assert(Offset >= 0
@@ -310,7 +316,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
   // so we adjust 'Offset' to point to the end of last fixed sized
   // preallocated object.
   for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
-    int FixedOff;
+    int64_t FixedOff;
     if (StackGrowsDown) {
       // The maximum distance from the stack pointer is at lower address of
       // the object -- which is given by offset. For down growing stack
@@ -361,11 +367,37 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
     }
   }
 
+  // Make sure the special register scavenging spill slot is closest to the
+  // frame pointer if a frame pointer is required.
+  const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
+  if (RS && RegInfo->hasFP(Fn)) {
+    int SFI = RS->getScavengingFrameIndex();
+    if (SFI >= 0) {
+      // If stack grows down, we need to add size of find the lowest
+      // address of the object.
+      if (StackGrowsDown)
+        Offset += FFI->getObjectSize(SFI);
+
+      unsigned Align = FFI->getObjectAlignment(SFI);
+      // Adjust to alignment boundary
+      Offset = (Offset+Align-1)/Align*Align;
+
+      if (StackGrowsDown) {
+        FFI->setObjectOffset(SFI, -Offset);        // Set the computed offset
+      } else {
+        FFI->setObjectOffset(SFI, Offset);
+        Offset += FFI->getObjectSize(SFI);
+      }
+    }
+  }
+
   // Then assign frame offsets to stack objects that are not used to spill
   // callee saved registers.
   for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
     if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
       continue;
+    if (RS && (int)i == RS->getScavengingFrameIndex())
+      continue;
 
     // If stack grows down, we need to add size of find the lowest
     // address of the object.
@@ -387,7 +419,45 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
     }
   }
 
-  // Set the final value of the stack pointer...
+  // Make sure the special register scavenging spill slot is closest to the
+  // stack pointer.
+  if (RS) {
+    int SFI = RS->getScavengingFrameIndex();
+    if (SFI >= 0) {
+      // If stack grows down, we need to add size of find the lowest
+      // address of the object.
+      if (StackGrowsDown)
+        Offset += FFI->getObjectSize(SFI);
+
+      unsigned Align = FFI->getObjectAlignment(SFI);
+      // Adjust to alignment boundary
+      Offset = (Offset+Align-1)/Align*Align;
+
+      if (StackGrowsDown) {
+        FFI->setObjectOffset(SFI, -Offset);        // Set the computed offset
+      } else {
+        FFI->setObjectOffset(SFI, Offset);
+        Offset += FFI->getObjectSize(SFI);
+      }
+    }
+  }
+
+  // Round up the size to a multiple of the alignment, but only if there are
+  // calls or alloca's in the function.  This ensures that any calls to
+  // subroutines have their stack frames suitable aligned.
+  if (!RegInfo->targetHandlesStackFrameRounding() &&
+      (FFI->hasCalls() || FFI->hasVarSizedObjects())) {
+    // When we have no frame pointer, we reserve argument space for call sites
+    // in the function immediately on entry to the current function. This
+    // eliminates the need for add/sub sp brackets around call sites.
+    if (!RegInfo->hasFP(Fn))
+      Offset += FFI->getMaxCallFrameSize();
+
+    unsigned AlignMask = TFI.getStackAlignment() - 1;
+    Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
+  }
+
+  // Update frame info to pretend that this is part of the stack...
   FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea());
 
   // Remember the required stack alignment in case targets need it to perform
@@ -425,13 +495,24 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
   assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
   const MRegisterInfo &MRI = *TM.getRegisterInfo();
 
-  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
-    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
-      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
-        if (I->getOperand(i).isFrameIndex()) {
+  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+    if (RS) RS->enterBasicBlock(BB);
+    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
+      MachineInstr *MI = I++;
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
+        if (MI->getOperand(i).isFrameIndex()) {
           // If this instruction has a FrameIndex operand, we need to use that
           // target machine register info object to eliminate it.
-          MRI.eliminateFrameIndex(I);
+          MRI.eliminateFrameIndex(MI, RS);
+
+          // Revisit the instruction in full.  Some instructions (e.g. inline
+          // asm instructions) can have multiple frame indices.
+          --I;
+          MI = 0;
           break;
         }
+      // Update register states.
+      if (RS && MI) RS->forward(MI);
+    }
+  }
 }