LLVM API Documentation

MSP430FrameLowering.cpp
Go to the documentation of this file.
00001 //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the MSP430 implementation of TargetFrameLowering class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "MSP430FrameLowering.h"
00015 #include "MSP430InstrInfo.h"
00016 #include "MSP430MachineFunctionInfo.h"
00017 #include "MSP430Subtarget.h"
00018 #include "llvm/CodeGen/MachineFrameInfo.h"
00019 #include "llvm/CodeGen/MachineFunction.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/CodeGen/MachineModuleInfo.h"
00022 #include "llvm/CodeGen/MachineRegisterInfo.h"
00023 #include "llvm/IR/DataLayout.h"
00024 #include "llvm/IR/Function.h"
00025 #include "llvm/Support/CommandLine.h"
00026 #include "llvm/Target/TargetOptions.h"
00027 
00028 using namespace llvm;
00029 
00030 bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
00031   const MachineFrameInfo *MFI = MF.getFrameInfo();
00032 
00033   return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
00034           MF.getFrameInfo()->hasVarSizedObjects() ||
00035           MFI->isFrameAddressTaken());
00036 }
00037 
00038 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
00039   return !MF.getFrameInfo()->hasVarSizedObjects();
00040 }
00041 
00042 void MSP430FrameLowering::emitPrologue(MachineFunction &MF) const {
00043   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
00044   MachineFrameInfo *MFI = MF.getFrameInfo();
00045   MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
00046   const MSP430InstrInfo &TII =
00047       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
00048 
00049   MachineBasicBlock::iterator MBBI = MBB.begin();
00050   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00051 
00052   // Get the number of bytes to allocate from the FrameInfo.
00053   uint64_t StackSize = MFI->getStackSize();
00054 
00055   uint64_t NumBytes = 0;
00056   if (hasFP(MF)) {
00057     // Calculate required stack adjustment
00058     uint64_t FrameSize = StackSize - 2;
00059     NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
00060 
00061     // Get the offset of the stack slot for the EBP register... which is
00062     // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
00063     // Update the frame offset adjustment.
00064     MFI->setOffsetAdjustment(-NumBytes);
00065 
00066     // Save FP into the appropriate stack slot...
00067     BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
00068       .addReg(MSP430::FP, RegState::Kill);
00069 
00070     // Update FP with the new base value...
00071     BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP)
00072       .addReg(MSP430::SP);
00073 
00074     // Mark the FramePtr as live-in in every block except the entry.
00075     for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
00076          I != E; ++I)
00077       I->addLiveIn(MSP430::FP);
00078 
00079   } else
00080     NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
00081 
00082   // Skip the callee-saved push instructions.
00083   while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
00084     ++MBBI;
00085 
00086   if (MBBI != MBB.end())
00087     DL = MBBI->getDebugLoc();
00088 
00089   if (NumBytes) { // adjust stack pointer: SP -= numbytes
00090     // If there is an SUB16ri of SP immediately before this instruction, merge
00091     // the two.
00092     //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
00093     // If there is an ADD16ri or SUB16ri of SP immediately after this
00094     // instruction, merge the two instructions.
00095     // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
00096 
00097     if (NumBytes) {
00098       MachineInstr *MI =
00099         BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
00100         .addReg(MSP430::SP).addImm(NumBytes);
00101       // The SRW implicit def is dead.
00102       MI->getOperand(3).setIsDead();
00103     }
00104   }
00105 }
00106 
00107 void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
00108                                        MachineBasicBlock &MBB) const {
00109   const MachineFrameInfo *MFI = MF.getFrameInfo();
00110   MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
00111   const MSP430InstrInfo &TII =
00112       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
00113 
00114   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
00115   unsigned RetOpcode = MBBI->getOpcode();
00116   DebugLoc DL = MBBI->getDebugLoc();
00117 
00118   switch (RetOpcode) {
00119   case MSP430::RET:
00120   case MSP430::RETI: break;  // These are ok
00121   default:
00122     llvm_unreachable("Can only insert epilog into returning blocks");
00123   }
00124 
00125   // Get the number of bytes to allocate from the FrameInfo
00126   uint64_t StackSize = MFI->getStackSize();
00127   unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
00128   uint64_t NumBytes = 0;
00129 
00130   if (hasFP(MF)) {
00131     // Calculate required stack adjustment
00132     uint64_t FrameSize = StackSize - 2;
00133     NumBytes = FrameSize - CSSize;
00134 
00135     // pop FP.
00136     BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP);
00137   } else
00138     NumBytes = StackSize - CSSize;
00139 
00140   // Skip the callee-saved pop instructions.
00141   while (MBBI != MBB.begin()) {
00142     MachineBasicBlock::iterator PI = std::prev(MBBI);
00143     unsigned Opc = PI->getOpcode();
00144     if (Opc != MSP430::POP16r && !PI->isTerminator())
00145       break;
00146     --MBBI;
00147   }
00148 
00149   DL = MBBI->getDebugLoc();
00150 
00151   // If there is an ADD16ri or SUB16ri of SP immediately before this
00152   // instruction, merge the two instructions.
00153   //if (NumBytes || MFI->hasVarSizedObjects())
00154   //  mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
00155 
00156   if (MFI->hasVarSizedObjects()) {
00157     BuildMI(MBB, MBBI, DL,
00158             TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::FP);
00159     if (CSSize) {
00160       MachineInstr *MI =
00161         BuildMI(MBB, MBBI, DL,
00162                 TII.get(MSP430::SUB16ri), MSP430::SP)
00163         .addReg(MSP430::SP).addImm(CSSize);
00164       // The SRW implicit def is dead.
00165       MI->getOperand(3).setIsDead();
00166     }
00167   } else {
00168     // adjust stack pointer back: SP += numbytes
00169     if (NumBytes) {
00170       MachineInstr *MI =
00171         BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
00172         .addReg(MSP430::SP).addImm(NumBytes);
00173       // The SRW implicit def is dead.
00174       MI->getOperand(3).setIsDead();
00175     }
00176   }
00177 }
00178 
00179 // FIXME: Can we eleminate these in favour of generic code?
00180 bool
00181 MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
00182                                            MachineBasicBlock::iterator MI,
00183                                         const std::vector<CalleeSavedInfo> &CSI,
00184                                         const TargetRegisterInfo *TRI) const {
00185   if (CSI.empty())
00186     return false;
00187 
00188   DebugLoc DL;
00189   if (MI != MBB.end()) DL = MI->getDebugLoc();
00190 
00191   MachineFunction &MF = *MBB.getParent();
00192   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
00193   MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
00194   MFI->setCalleeSavedFrameSize(CSI.size() * 2);
00195 
00196   for (unsigned i = CSI.size(); i != 0; --i) {
00197     unsigned Reg = CSI[i-1].getReg();
00198     // Add the callee-saved register as live-in. It's killed at the spill.
00199     MBB.addLiveIn(Reg);
00200     BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
00201       .addReg(Reg, RegState::Kill);
00202   }
00203   return true;
00204 }
00205 
00206 bool
00207 MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
00208                                                  MachineBasicBlock::iterator MI,
00209                                         const std::vector<CalleeSavedInfo> &CSI,
00210                                         const TargetRegisterInfo *TRI) const {
00211   if (CSI.empty())
00212     return false;
00213 
00214   DebugLoc DL;
00215   if (MI != MBB.end()) DL = MI->getDebugLoc();
00216 
00217   MachineFunction &MF = *MBB.getParent();
00218   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
00219 
00220   for (unsigned i = 0, e = CSI.size(); i != e; ++i)
00221     BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
00222 
00223   return true;
00224 }
00225 
00226 void MSP430FrameLowering::
00227 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00228                               MachineBasicBlock::iterator I) const {
00229   const MSP430InstrInfo &TII =
00230       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
00231   unsigned StackAlign = getStackAlignment();
00232 
00233   if (!hasReservedCallFrame(MF)) {
00234     // If the stack pointer can be changed after prologue, turn the
00235     // adjcallstackup instruction into a 'sub SP, <amt>' and the
00236     // adjcallstackdown instruction into 'add SP, <amt>'
00237     // TODO: consider using push / pop instead of sub + store / add
00238     MachineInstr *Old = I;
00239     uint64_t Amount = Old->getOperand(0).getImm();
00240     if (Amount != 0) {
00241       // We need to keep the stack aligned properly.  To do this, we round the
00242       // amount of space needed for the outgoing arguments up to the next
00243       // alignment boundary.
00244       Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
00245 
00246       MachineInstr *New = nullptr;
00247       if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
00248         New = BuildMI(MF, Old->getDebugLoc(),
00249                       TII.get(MSP430::SUB16ri), MSP430::SP)
00250           .addReg(MSP430::SP).addImm(Amount);
00251       } else {
00252         assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
00253         // factor out the amount the callee already popped.
00254         uint64_t CalleeAmt = Old->getOperand(1).getImm();
00255         Amount -= CalleeAmt;
00256         if (Amount)
00257           New = BuildMI(MF, Old->getDebugLoc(),
00258                         TII.get(MSP430::ADD16ri), MSP430::SP)
00259             .addReg(MSP430::SP).addImm(Amount);
00260       }
00261 
00262       if (New) {
00263         // The SRW implicit def is dead.
00264         New->getOperand(3).setIsDead();
00265 
00266         // Replace the pseudo instruction with a new instruction...
00267         MBB.insert(I, New);
00268       }
00269     }
00270   } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
00271     // If we are performing frame pointer elimination and if the callee pops
00272     // something off the stack pointer, add it back.
00273     if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
00274       MachineInstr *Old = I;
00275       MachineInstr *New =
00276         BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
00277                 MSP430::SP).addReg(MSP430::SP).addImm(CalleeAmt);
00278       // The SRW implicit def is dead.
00279       New->getOperand(3).setIsDead();
00280 
00281       MBB.insert(I, New);
00282     }
00283   }
00284 
00285   MBB.erase(I);
00286 }
00287 
00288 void
00289 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
00290                                                          RegScavenger *) const {
00291   // Create a frame entry for the FP register that must be saved.
00292   if (hasFP(MF)) {
00293     int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
00294     (void)FrameIdx;
00295     assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
00296            "Slot for FP register must be last in order to be found!");
00297   }
00298 }