Actually, change it to use explicit new/delete, which is more likely to be
[oota-llvm.git] / lib / CodeGen / PrologEpilogInserter.cpp
index adf6308eef30ef75f118ddd3539cc66bbabcb122..06de9bf0240f559eb047a0f7588ce59133e26b84 100644 (file)
@@ -9,19 +9,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Pass.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/FunctionFrameInfo.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MRegisterInfo.h"
-#include "llvm/Target/MachineFrameInfo.h"
-#include "llvm/Target/MachineInstrInfo.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
 
 namespace {
-  struct PEI : public FunctionPass {
-    bool runOnFunction(Function &Fn) {
-      return runOnMachineFunction(MachineFunction::get(&Fn));
+  struct PEI : public MachineFunctionPass {
+    const char *getPassName() const {
+      return "Prolog/Epilog Insertion & Frame Finalization";
     }
 
     /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
@@ -41,13 +41,13 @@ namespace {
       // Calculate actual frame offsets for all of the abstract stack objects...
       calculateFrameObjectOffsets(Fn);
 
+      // Add prolog and epilog code to the function.
+      insertPrologEpilogCode(Fn);
+
       // Replace all MO_FrameIndex operands with physical register references
       // and actual offsets.
       //
       replaceFrameIndices(Fn);
-
-      // Add prolog and epilog code to the function.
-      insertPrologEpilogCode(Fn);
       return true;
     }
 
@@ -108,13 +108,14 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
          MachineOperand &MO = (*I)->getOperand(i);
          assert(!MO.isVirtualRegister() &&
                 "Register allocation must be performed!");
-         if (MO.isPhysicalRegister() && MO.opIsDef())
+         if (MO.isPhysicalRegister() &&
+             (MO.opIsDefOnly() || MO.opIsDefAndUse()))
            ModifiedRegs[MO.getReg()] = true;         // Register is modified
        }
        ++I;
       }
 
-  FunctionFrameInfo *FFI = Fn.getFrameInfo();
+  MachineFrameInfo *FFI = Fn.getFrameInfo();
   FFI->setHasCalls(HasCalls);
   FFI->setMaxCallFrameSize(MaxCallFrameSize);
 
@@ -141,8 +142,7 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
   // stack slots for them.
   std::vector<int> StackSlots;
   for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
-    const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]);
-    int FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment());
+    int FrameIdx = FFI->CreateStackObject(RegInfo->getRegClass(RegsToSave[i]));
     StackSlots.push_back(FrameIdx);
   }
 
@@ -158,10 +158,10 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) {
   }
 
   // Add code to restore the callee-save registers in each exiting block.
-  const MachineInstrInfo &MII = Fn.getTarget().getInstrInfo();
+  const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
   for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) {
     // If last instruction is a return instruction, add an epilogue
-    if (MII.isReturn(FI->back()->getOpcode())) {
+    if (!FI->empty() && TII.isReturn(FI->back()->getOpcode())) {
       MBB = FI; I = MBB->end()-1;
 
       for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
@@ -185,25 +185,46 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
   assert(StackGrowsDown && "Only tested on stack down growing targets!");
  
   // Loop over all of the stack objects, assigning sequential addresses...
-  FunctionFrameInfo *FFI = Fn.getFrameInfo();
+  MachineFrameInfo *FFI = Fn.getFrameInfo();
+
+  unsigned StackAlignment = TFI.getStackAlignment();
 
   // Start at the beginning of the local area...
-  int Offset = -TFI.getOffsetOfLocalArea();
+  int Offset = TFI.getOffsetOfLocalArea();
   for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
     Offset += FFI->getObjectSize(i);         // Allocate Size bytes...
 
     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...
     
     FFI->setObjectOffset(i, -Offset);        // Set the computed offset
   }
 
   // Align the final stack pointer offset...
-  unsigned StackAlign = TFI.getStackAlignment();
-  Offset = (Offset+StackAlign-1)/StackAlign*StackAlign;
+  Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment;
 
   // Set the final value of the stack pointer...
-  FFI->setStackSize(Offset);
+  FFI->setStackSize(Offset-TFI.getOffsetOfLocalArea());
+}
+
+
+/// insertPrologEpilogCode - Scan the function for modified caller saved
+/// registers, insert spill code for these caller saved registers, then add
+/// prolog and epilog code to the function.
+///
+void PEI::insertPrologEpilogCode(MachineFunction &Fn) {
+  // Add prologue to the function...
+  Fn.getTarget().getRegisterInfo()->emitPrologue(Fn);
+
+  // Add epilogue to restore the callee-save registers in each exiting block
+  const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
+  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
+    // If last instruction is a return instruction, add an epilogue
+    if (!I->empty() && TII.isReturn(I->back()->getOpcode()))
+      Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I);
+  }
 }
 
 
@@ -227,21 +248,3 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
          break;
        }
 }
-
-
-/// insertPrologEpilogCode - Scan the function for modified caller saved
-/// registers, insert spill code for these caller saved registers, then add
-/// prolog and epilog code to the function.
-///
-void PEI::insertPrologEpilogCode(MachineFunction &Fn) {
-  // Add prologue to the function...
-  Fn.getTarget().getRegisterInfo()->emitPrologue(Fn);
-
-  // Add epilogue to restore the callee-save registers in each exiting block
-  const MachineInstrInfo &MII = Fn.getTarget().getInstrInfo();
-  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
-    // If last instruction is a return instruction, add an epilogue
-    if (MII.isReturn(I->back()->getOpcode()))
-      Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I);
-  }
-}