Make $fp and $ra callee-saved registers and let PrologEpilogInserter handle
authorAkira Hatanaka <ahatanak@gmail.com>
Fri, 20 May 2011 18:39:33 +0000 (18:39 +0000)
committerAkira Hatanaka <ahatanak@gmail.com>
Fri, 20 May 2011 18:39:33 +0000 (18:39 +0000)
saving and restoring them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131745 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsFrameLowering.cpp
lib/Target/Mips/MipsFrameLowering.h
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsMachineFunction.h
lib/Target/Mips/MipsRegisterInfo.cpp
test/CodeGen/Mips/i64arg.ll

index 21e3314a666994c1936bc7360de666a59a949755..819feedb607ee8a6f8d39e99273b6f033770b18d 100644 (file)
@@ -156,26 +156,6 @@ void MipsFrameLowering::adjustMipsStackFrame(MachineFunction &MF) const {
     StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
   }
 
-  // Stack locations for FP and RA. If only one of them is used,
-  // the space must be allocated for both, otherwise no space at all.
-  if (hasFP(MF) || MFI->adjustsStack()) {
-    // FP stack location
-    MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
-                         StackOffset);
-    MipsFI->setFPStackOffset(StackOffset);
-    TopCPUSavedRegOff = StackOffset;
-    StackOffset += RegSize;
-
-    // SP stack location
-    MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
-                         StackOffset);
-    MipsFI->setRAStackOffset(StackOffset);
-    StackOffset += RegSize;
-
-    if (MFI->adjustsStack())
-      TopCPUSavedRegOff += RegSize;
-  }
-
   StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
 
   // Adjust FPU Callee Saved Registers Area. This Area must be
@@ -267,9 +247,6 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
   // No need to allocate space on the stack.
   if (StackSize == 0 && !MFI->adjustsStack()) return;
 
-  int FPOffset = MipsFI->getFPStackOffset();
-  int RAOffset = MipsFI->getRAStackOffset();
-
   BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
 
   // TODO: check need from GP here.
@@ -288,36 +265,11 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
   if (ATUsed)
     BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
 
-  // Save the return address only if the function isn't a leaf one.
-  // sw  $ra, stack_loc($sp)
-  if (MFI->adjustsStack()) {
-    ATUsed = expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB,
-                                   MBBI);
-    BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
-      .addReg(Mips::RA).addImm(NewImm).addReg(NewReg);
-
-    // FIXME: change this when mips goes MC".
-    if (ATUsed)
-      BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
-  }
-
-  // if framepointer enabled, save it and set it
-  // to point to the stack pointer
-  if (hasFP(MF)) {
-    // sw  $fp,stack_loc($sp)
-    ATUsed = expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB,
-                                   MBBI);
-    BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
-      .addReg(Mips::FP).addImm(NewImm).addReg(NewReg);
-
-    // FIXME: change this when mips goes MC".
-    if (ATUsed)
-      BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
-
+  // if framepointer enabled, set it to point to the stack pointer.
+  if (hasFP(MF))
     // move $fp, $sp
     BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
       .addReg(Mips::SP).addReg(Mips::ZERO);
-  }
 
   // Restore GP from the saved stack location
   if (MipsFI->needGPSaveRestore())
@@ -329,7 +281,6 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
                                  MachineBasicBlock &MBB) const {
   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
   MachineFrameInfo *MFI            = MF.getFrameInfo();
-  MipsFunctionInfo *MipsFI         = MF.getInfo<MipsFunctionInfo>();
   const MipsInstrInfo &TII =
     *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
   DebugLoc dl = MBBI->getDebugLoc();
@@ -337,45 +288,16 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
   // Get the number of bytes from FrameInfo
   int NumBytes = (int) MFI->getStackSize();
 
-  // Get the FI's where RA and FP are saved.
-  int FPOffset = MipsFI->getFPStackOffset();
-  int RAOffset = MipsFI->getRAStackOffset();
-
   unsigned NewReg = 0;
   int NewImm = 0;
   bool ATUsed = false;
 
-  // if framepointer enabled, restore it and restore the
-  // stack pointer
-  if (hasFP(MF)) {
+  // if framepointer enabled, restore the stack pointer.
+  if (hasFP(MF))
     // move $sp, $fp
     BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::SP)
       .addReg(Mips::FP).addReg(Mips::ZERO);
 
-    // lw  $fp,stack_loc($sp)
-    ATUsed = expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB,
-                                   MBBI);
-    BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::FP)
-      .addImm(NewImm).addReg(NewReg);
-
-    // FIXME: change this when mips goes MC".
-    if (ATUsed)
-      BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
-  }
-
-  // Restore the return address only if the function isn't a leaf one.
-  // lw  $ra, stack_loc($sp)
-  if (MFI->adjustsStack()) {
-    ATUsed = expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB,
-                                   MBBI);
-    BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::RA)
-      .addImm(NewImm).addReg(NewReg);
-
-    // FIXME: change this when mips goes MC".
-    if (ATUsed)
-      BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
-  }
-
   // adjust stack  : insert addi sp, sp, (imm)
   if (NumBytes) {
     ATUsed = expandRegLargeImmPair(Mips::SP, NumBytes, NewReg, NewImm, MBB,
@@ -389,6 +311,30 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
   }
 }
 
+void MipsFrameLowering::
+processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+                                     RegScavenger *RS) const {
+  MachineRegisterInfo& MRI = MF.getRegInfo();
+  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+
+  // FIXME: remove this code if register allocator can correctly mark
+  //        $fp and $ra used or unused.
+
+  // Mark $fp and $ra as used or unused.
+  if (hasFP(MF))
+    MRI.setPhysRegUsed(Mips::FP);
+
+  // The register allocator might determine $ra is used after seeing 
+  // instruction "jr $ra", but we do not want PrologEpilogInserter to insert
+  // instructions to save/restore $ra unless there is a function call.
+  // To correct this, $ra is explicitly marked unused if there is no
+  // function call.
+  if (MipsFI->hasCall())
+    MRI.setPhysRegUsed(Mips::RA);
+  else
+    MRI.setPhysRegUnused(Mips::RA);
+}
+
 void MipsFrameLowering::
 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
   const MipsRegisterInfo *RegInfo =
index 34647df4f354a59b6028f57d144a4881e7f9c723..f42711da841dff1623d0561e44b0403a25bf9bf2 100644 (file)
@@ -40,6 +40,8 @@ public:
 
   bool hasFP(const MachineFunction &MF) const;
 
+  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+                                            RegScavenger *RS) const;
   void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
 };
 
index ea26d57647f10aec5e59dca8cf4052da524a3220..08da34bcefceb342209b0f13e06d24772f70f7da 100644 (file)
@@ -1042,6 +1042,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
+  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
 
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
@@ -1066,6 +1067,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
   int LastArgStackLoc = 0;
   unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16);
 
+  MipsFI->setHasCall();
+
   // Walk the register/memloc assignments, inserting copies/loads.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     SDValue Arg = OutVals[i];
@@ -1226,7 +1229,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
       // Function can have an arbitrary number of calls, so
       // hold the LastArgStackLoc with the biggest offset.
       int FI;
-      MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
       if (LastArgStackLoc >= MipsFI->getGPStackOffset()) {
         LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4);
         // Create the frame index only once. SPOffset here can be anything
index 325619313dee451f5c2346583ee97be2c8196c1e..c4d2cfe7be347f523c38bc6ede57df4cb791baac 100644 (file)
@@ -27,14 +27,6 @@ namespace llvm {
 class MipsFunctionInfo : public MachineFunctionInfo {
 
 private:
-  /// Holds for each function where on the stack the Frame Pointer must be
-  /// saved. This is used on Prologue and Epilogue to emit FP save/restore
-  int FPStackOffset;
-
-  /// Holds for each function where on the stack the Return Address must be
-  /// saved. This is used on Prologue and Epilogue to emit RA save/restore
-  int RAStackOffset;
-
   /// At each function entry, two special bitmask directives must be emitted
   /// to help debugging, for CPU and FPU callee saved registers. Both need
   /// the negative offset from the final stack size and its higher registers
@@ -94,19 +86,13 @@ private:
   bool HasCall; // True if function has a function call.
 public:
   MipsFunctionInfo(MachineFunction& MF)
-  : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
+  : CPUTopSavedRegOff(0),
     FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
     HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0),
     VarArgsFrameIndex(0), InArgFIRange(std::make_pair(-1, 0)),
     OutArgFIRange(std::make_pair(-1, 0)), GPFI(0), HasCall(false)
   {}
 
-  int getFPStackOffset() const { return FPStackOffset; }
-  void setFPStackOffset(int Off) { FPStackOffset = Off; }
-
-  int getRAStackOffset() const { return RAStackOffset; }
-  void setRAStackOffset(int Off) { RAStackOffset = Off; }
-
   int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
   void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
 
index 5a717451235ec3739775b28f336307540d321e23..eb11550800d46e52e29d79b8317df394deafda88 100644 (file)
@@ -99,20 +99,20 @@ getCalleeSavedRegs(const MachineFunction *MF) const
   // Mips callee-save register range is $16-$23, $f20-$f30
   static const unsigned SingleFloatOnlyCalleeSavedRegs[] = {
     Mips::S0, Mips::S1, Mips::S2, Mips::S3,
-    Mips::S4, Mips::S5, Mips::S6, Mips::S7,
+    Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
     Mips::F20, Mips::F21, Mips::F22, Mips::F23, Mips::F24, Mips::F25,
     Mips::F26, Mips::F27, Mips::F28, Mips::F29, Mips::F30, 0
   };
 
   static const unsigned BitMode32CalleeSavedRegs[] = {
     Mips::S0, Mips::S1, Mips::S2, Mips::S3,
-    Mips::S4, Mips::S5, Mips::S6, Mips::S7,
+    Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
     Mips::F20, Mips::F22, Mips::F24, Mips::F26, Mips::F28, Mips::F30, 0
   };
 
   static const unsigned Mips32CalleeSavedRegs[] = {
     Mips::S0, Mips::S1, Mips::S2, Mips::S3,
-    Mips::S4, Mips::S5, Mips::S6, Mips::S7,
+    Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
     Mips::D10, Mips::D11, Mips::D12, Mips::D13, Mips::D14, Mips::D15, 0
   };
 
index 560f2e9b08740c2970efffedd6d093883a4faee3..9a30453a51fce49b52559f0b9e2fd5de70e6c347 100644 (file)
@@ -10,8 +10,8 @@ entry:
 ; CHECK: jalr
   tail call void @ff1(i32 %i, i64 1085102592623924856) nounwind
 ; CHECK: lw $25, %call16(ff2)
-; CHECK: lw $[[R2:[0-9]+]], 88($sp)
-; CHECK: lw $[[R3:[0-9]+]], 92($sp)
+; CHECK: lw $[[R2:[0-9]+]], 80($sp)
+; CHECK: lw $[[R3:[0-9]+]], 84($sp)
 ; CHECK: addu $4, $zero, $[[R2]]
 ; CHECK: addu $5, $zero, $[[R3]]
 ; CHECK: jalr $25