LLVM API Documentation

HexagonFrameLowering.cpp
Go to the documentation of this file.
00001 //===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
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 
00011 #include "HexagonFrameLowering.h"
00012 #include "Hexagon.h"
00013 #include "HexagonInstrInfo.h"
00014 #include "HexagonMachineFunctionInfo.h"
00015 #include "HexagonRegisterInfo.h"
00016 #include "HexagonSubtarget.h"
00017 #include "HexagonTargetMachine.h"
00018 #include "llvm/ADT/BitVector.h"
00019 #include "llvm/ADT/STLExtras.h"
00020 #include "llvm/CodeGen/AsmPrinter.h"
00021 #include "llvm/CodeGen/MachineFrameInfo.h"
00022 #include "llvm/CodeGen/MachineFunction.h"
00023 #include "llvm/CodeGen/MachineFunctionPass.h"
00024 #include "llvm/CodeGen/MachineInstrBuilder.h"
00025 #include "llvm/CodeGen/MachineModuleInfo.h"
00026 #include "llvm/CodeGen/MachineRegisterInfo.h"
00027 #include "llvm/CodeGen/RegisterScavenging.h"
00028 #include "llvm/IR/Function.h"
00029 #include "llvm/IR/Type.h"
00030 #include "llvm/MC/MCAsmInfo.h"
00031 #include "llvm/MC/MachineLocation.h"
00032 #include "llvm/Support/CommandLine.h"
00033 #include "llvm/Target/TargetInstrInfo.h"
00034 #include "llvm/Target/TargetMachine.h"
00035 #include "llvm/Target/TargetOptions.h"
00036 
00037 using namespace llvm;
00038 
00039 static cl::opt<bool> DisableDeallocRet(
00040                        "disable-hexagon-dealloc-ret",
00041                        cl::Hidden,
00042                        cl::desc("Disable Dealloc Return for Hexagon target"));
00043 
00044 /// determineFrameLayout - Determine the size of the frame and maximum call
00045 /// frame size.
00046 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
00047   MachineFrameInfo *MFI = MF.getFrameInfo();
00048 
00049   // Get the number of bytes to allocate from the FrameInfo.
00050   unsigned FrameSize = MFI->getStackSize();
00051 
00052   // Get the alignments provided by the target.
00053   unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
00054   // Get the maximum call frame size of all the calls.
00055   unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
00056 
00057   // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
00058   // that allocations will be aligned.
00059   if (MFI->hasVarSizedObjects())
00060     maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
00061 
00062   // Update maximum call frame size.
00063   MFI->setMaxCallFrameSize(maxCallFrameSize);
00064 
00065   // Include call frame size in total.
00066   FrameSize += maxCallFrameSize;
00067 
00068   // Make sure the frame is aligned.
00069   FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
00070 
00071   // Update frame info.
00072   MFI->setStackSize(FrameSize);
00073 }
00074 
00075 
00076 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
00077   MachineBasicBlock &MBB = MF.front();
00078   MachineFrameInfo *MFI = MF.getFrameInfo();
00079   MachineBasicBlock::iterator MBBI = MBB.begin();
00080   const HexagonRegisterInfo *QRI =
00081     static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
00082   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00083   determineFrameLayout(MF);
00084 
00085   // Get the number of bytes to allocate from the FrameInfo.
00086   int NumBytes = (int) MFI->getStackSize();
00087 
00088   // LLVM expects allocframe not to be the first instruction in the
00089   // basic block.
00090   MachineBasicBlock::iterator InsertPt = MBB.begin();
00091 
00092   //
00093   // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
00094   //
00095   HexagonMachineFunctionInfo *FuncInfo =
00096     MF.getInfo<HexagonMachineFunctionInfo>();
00097   const std::vector<MachineInstr*>& AdjustRegs =
00098     FuncInfo->getAllocaAdjustInsts();
00099   for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
00100          e = AdjustRegs.end();
00101        i != e; ++i) {
00102     MachineInstr* MI = *i;
00103     assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
00104            "Expected adjust alloca node");
00105 
00106     MachineOperand& MO = MI->getOperand(2);
00107     assert(MO.isImm() && "Expected immediate");
00108     MO.setImm(MFI->getMaxCallFrameSize());
00109   }
00110 
00111   //
00112   // Only insert ALLOCFRAME if we need to.
00113   //
00114   if (hasFP(MF)) {
00115     // Check for overflow.
00116     // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
00117     const int ALLOCFRAME_MAX = 16384;
00118     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
00119 
00120     if (NumBytes >= ALLOCFRAME_MAX) {
00121       // Emit allocframe(#0).
00122       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
00123 
00124       // Subtract offset from frame pointer.
00125       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
00126                                       HEXAGON_RESERVED_REG_1).addImm(NumBytes);
00127       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
00128                                       QRI->getStackRegister()).
00129                                       addReg(QRI->getStackRegister()).
00130                                       addReg(HEXAGON_RESERVED_REG_1);
00131     } else {
00132       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
00133     }
00134   }
00135 }
00136 // Returns true if MBB has a machine instructions that indicates a tail call
00137 // in the block.
00138 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
00139   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
00140   unsigned RetOpcode = MBBI->getOpcode();
00141 
00142   return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
00143 }
00144 
00145 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
00146                                      MachineBasicBlock &MBB) const {
00147   MachineBasicBlock::iterator MBBI = prior(MBB.end());
00148   DebugLoc dl = MBBI->getDebugLoc();
00149   //
00150   // Only insert deallocframe if we need to.  Also at -O0.  See comment
00151   // in emitPrologue above.
00152   //
00153   if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
00154     MachineBasicBlock::iterator MBBI = prior(MBB.end());
00155     MachineBasicBlock::iterator MBBI_end = MBB.end();
00156 
00157     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
00158     // Handle EH_RETURN.
00159     if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
00160       assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
00161       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
00162       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
00163               Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
00164       return;
00165     }
00166     // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
00167     // versions.
00168     if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
00169                         && !DisableDeallocRet) {
00170       // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
00171       // instruction if we encounter it.
00172       MachineBasicBlock::iterator BeforeJMPR =
00173         MBB.begin() == MBBI ? MBBI : prior(MBBI);
00174       if (BeforeJMPR != MBBI &&
00175           BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
00176         // Remove the JMPR node.
00177         MBB.erase(MBBI);
00178         return;
00179       }
00180 
00181       // Add dealloc_return.
00182       MachineInstrBuilder MIB =
00183         BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
00184       // Transfer the function live-out registers.
00185       MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
00186       // Remove the JUMPR node.
00187       MBB.erase(MBBI);
00188     } else { // Add deallocframe for V2 and V3, and V4 tail calls.
00189       // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
00190       // DEALLOCFRAME instruction after it.
00191       MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
00192       MachineBasicBlock::iterator I =
00193         Term == MBB.begin() ?  MBB.end() : prior(Term);
00194       if (I != MBB.end() &&
00195           I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
00196         return;
00197 
00198       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
00199     }
00200   }
00201 }
00202 
00203 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
00204   const MachineFrameInfo *MFI = MF.getFrameInfo();
00205   const HexagonMachineFunctionInfo *FuncInfo =
00206     MF.getInfo<HexagonMachineFunctionInfo>();
00207   return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
00208           FuncInfo->hasClobberLR() );
00209 }
00210 
00211 static inline
00212 unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
00213   MCSuperRegIterator SRI(Reg, TRI);
00214   assert(SRI.isValid() && "Expected a superreg");
00215   unsigned SuperReg = *SRI;
00216   ++SRI;
00217   assert(!SRI.isValid() && "Expected exactly one superreg");
00218   return SuperReg;
00219 }
00220 
00221 bool
00222 HexagonFrameLowering::spillCalleeSavedRegisters(
00223                                         MachineBasicBlock &MBB,
00224                                         MachineBasicBlock::iterator MI,
00225                                         const std::vector<CalleeSavedInfo> &CSI,
00226                                         const TargetRegisterInfo *TRI) const {
00227   MachineFunction *MF = MBB.getParent();
00228   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
00229 
00230   if (CSI.empty()) {
00231     return false;
00232   }
00233 
00234   // We can only schedule double loads if we spill contiguous callee-saved regs
00235   // For instance, we cannot scheduled double-word loads if we spill r24,
00236   // r26, and r27.
00237   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
00238   // above.
00239   bool ContiguousRegs = true;
00240 
00241   for (unsigned i = 0; i < CSI.size(); ++i) {
00242     unsigned Reg = CSI[i].getReg();
00243 
00244     //
00245     // Check if we can use a double-word store.
00246     //
00247     unsigned SuperReg = uniqueSuperReg(Reg, TRI);
00248     bool CanUseDblStore = false;
00249     const TargetRegisterClass* SuperRegClass = 0;
00250 
00251     if (ContiguousRegs && (i < CSI.size()-1)) {
00252       unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
00253       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
00254       CanUseDblStore = (SuperRegNext == SuperReg);
00255     }
00256 
00257 
00258     if (CanUseDblStore) {
00259       TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
00260                               CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
00261       MBB.addLiveIn(SuperReg);
00262       ++i;
00263     } else {
00264       // Cannot use a double-word store.
00265       ContiguousRegs = false;
00266       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
00267       TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
00268                               TRI);
00269       MBB.addLiveIn(Reg);
00270     }
00271   }
00272   return true;
00273 }
00274 
00275 
00276 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
00277                                         MachineBasicBlock &MBB,
00278                                         MachineBasicBlock::iterator MI,
00279                                         const std::vector<CalleeSavedInfo> &CSI,
00280                                         const TargetRegisterInfo *TRI) const {
00281 
00282   MachineFunction *MF = MBB.getParent();
00283   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
00284 
00285   if (CSI.empty()) {
00286     return false;
00287   }
00288 
00289   // We can only schedule double loads if we spill contiguous callee-saved regs
00290   // For instance, we cannot scheduled double-word loads if we spill r24,
00291   // r26, and r27.
00292   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
00293   // above.
00294   bool ContiguousRegs = true;
00295 
00296   for (unsigned i = 0; i < CSI.size(); ++i) {
00297     unsigned Reg = CSI[i].getReg();
00298 
00299     //
00300     // Check if we can use a double-word load.
00301     //
00302     unsigned SuperReg = uniqueSuperReg(Reg, TRI);
00303     const TargetRegisterClass* SuperRegClass = 0;
00304     bool CanUseDblLoad = false;
00305     if (ContiguousRegs && (i < CSI.size()-1)) {
00306       unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
00307       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
00308       CanUseDblLoad = (SuperRegNext == SuperReg);
00309     }
00310 
00311 
00312     if (CanUseDblLoad) {
00313       TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
00314                                SuperRegClass, TRI);
00315       MBB.addLiveIn(SuperReg);
00316       ++i;
00317     } else {
00318       // Cannot use a double-word load.
00319       ContiguousRegs = false;
00320       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
00321       TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
00322       MBB.addLiveIn(Reg);
00323     }
00324   }
00325   return true;
00326 }
00327 
00328 void HexagonFrameLowering::
00329 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00330                               MachineBasicBlock::iterator I) const {
00331   MachineInstr &MI = *I;
00332 
00333   if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
00334     // Hexagon_TODO: add code
00335   } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
00336     // Hexagon_TODO: add code
00337   } else {
00338     llvm_unreachable("Cannot handle this call frame pseudo instruction");
00339   }
00340   MBB.erase(I);
00341 }
00342 
00343 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
00344                                               int FI) const {
00345   return MF.getFrameInfo()->getObjectOffset(FI);
00346 }