[llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Aug 12 12:01:27 PDT 2004



Changes in directory llvm/lib/CodeGen:

PrologEpilogInserter.cpp updated: 1.27 -> 1.28
---
Log message:

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.


---
Diffs of the changes:  (+52 -9)

Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.27 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.28
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.27	Sat Aug  7 02:18:41 2004
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp	Thu Aug 12 14:01:14 2004
@@ -40,6 +40,9 @@
       // 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 @@
       // 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 @@
 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 @@
   // 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 @@
   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...






More information about the llvm-commits mailing list