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