Home | History | Annotate | Download | only in Hexagon
      1 //===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #include "HexagonFrameLowering.h"
     12 #include "Hexagon.h"
     13 #include "HexagonInstrInfo.h"
     14 #include "HexagonRegisterInfo.h"
     15 #include "HexagonSubtarget.h"
     16 #include "HexagonTargetMachine.h"
     17 #include "HexagonMachineFunctionInfo.h"
     18 #include "llvm/Function.h"
     19 #include "llvm/Type.h"
     20 #include "llvm/ADT/BitVector.h"
     21 #include "llvm/ADT/STLExtras.h"
     22 #include "llvm/CodeGen/AsmPrinter.h"
     23 #include "llvm/CodeGen/MachineInstrBuilder.h"
     24 #include "llvm/CodeGen/MachineFunction.h"
     25 #include "llvm/CodeGen/MachineFunctionPass.h"
     26 #include "llvm/CodeGen/MachineFrameInfo.h"
     27 #include "llvm/CodeGen/MachineModuleInfo.h"
     28 #include "llvm/CodeGen/MachineRegisterInfo.h"
     29 #include "llvm/CodeGen/RegisterScavenging.h"
     30 #include "llvm/MC/MachineLocation.h"
     31 #include "llvm/MC/MCAsmInfo.h"
     32 #include "llvm/Target/TargetInstrInfo.h"
     33 #include "llvm/Target/TargetMachine.h"
     34 #include "llvm/Target/TargetOptions.h"
     35 #include "llvm/Support/CommandLine.h"
     36 
     37 using namespace llvm;
     38 
     39 static cl::opt<bool> DisableDeallocRet(
     40                        "disable-hexagon-dealloc-ret",
     41                        cl::Hidden,
     42                        cl::desc("Disable Dealloc Return for Hexagon target"));
     43 
     44 /// determineFrameLayout - Determine the size of the frame and maximum call
     45 /// frame size.
     46 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
     47   MachineFrameInfo *MFI = MF.getFrameInfo();
     48 
     49   // Get the number of bytes to allocate from the FrameInfo.
     50   unsigned FrameSize = MFI->getStackSize();
     51 
     52   // Get the alignments provided by the target.
     53   unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
     54   // Get the maximum call frame size of all the calls.
     55   unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
     56 
     57   // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
     58   // that allocations will be aligned.
     59   if (MFI->hasVarSizedObjects())
     60     maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
     61 
     62   // Update maximum call frame size.
     63   MFI->setMaxCallFrameSize(maxCallFrameSize);
     64 
     65   // Include call frame size in total.
     66   FrameSize += maxCallFrameSize;
     67 
     68   // Make sure the frame is aligned.
     69   FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
     70 
     71   // Update frame info.
     72   MFI->setStackSize(FrameSize);
     73 }
     74 
     75 
     76 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
     77   MachineBasicBlock &MBB = MF.front();
     78   MachineFrameInfo *MFI = MF.getFrameInfo();
     79   MachineModuleInfo &MMI = MF.getMMI();
     80   MachineBasicBlock::iterator MBBI = MBB.begin();
     81   const HexagonRegisterInfo *QRI =
     82     static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
     83   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
     84   determineFrameLayout(MF);
     85 
     86   // Check if frame moves are needed for EH.
     87   bool needsFrameMoves = MMI.hasDebugInfo() ||
     88     !MF.getFunction()->needsUnwindTableEntry();
     89 
     90   // Get the number of bytes to allocate from the FrameInfo.
     91   int NumBytes = (int) MFI->getStackSize();
     92 
     93   // LLVM expects allocframe not to be the first instruction in the
     94   // basic block.
     95   MachineBasicBlock::iterator InsertPt = MBB.begin();
     96 
     97   //
     98   // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
     99   //
    100   HexagonMachineFunctionInfo *FuncInfo =
    101     MF.getInfo<HexagonMachineFunctionInfo>();
    102   const std::vector<MachineInstr*>& AdjustRegs =
    103     FuncInfo->getAllocaAdjustInsts();
    104   for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
    105          e = AdjustRegs.end();
    106        i != e; ++i) {
    107     MachineInstr* MI = *i;
    108     assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
    109            "Expected adjust alloca node");
    110 
    111     MachineOperand& MO = MI->getOperand(2);
    112     assert(MO.isImm() && "Expected immediate");
    113     MO.setImm(MFI->getMaxCallFrameSize());
    114   }
    115 
    116  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
    117 
    118  if (needsFrameMoves) {
    119    // Advance CFA. DW_CFA_def_cfa
    120    unsigned FPReg = QRI->getFrameRegister();
    121    unsigned RAReg = QRI->getRARegister();
    122 
    123    MachineLocation Dst(MachineLocation::VirtualFP);
    124    MachineLocation Src(FPReg, -8);
    125    Moves.push_back(MachineMove(0, Dst, Src));
    126 
    127    // R31 = (R31 - #4)
    128    MachineLocation LRDst(RAReg, -4);
    129    MachineLocation LRSrc(RAReg);
    130    Moves.push_back(MachineMove(0, LRDst, LRSrc));
    131 
    132    // R30 = (R30 - #8)
    133    MachineLocation SPDst(FPReg, -8);
    134    MachineLocation SPSrc(FPReg);
    135    Moves.push_back(MachineMove(0, SPDst, SPSrc));
    136  }
    137 
    138   //
    139   // Only insert ALLOCFRAME if we need to.
    140   //
    141   if (hasFP(MF)) {
    142     // Check for overflow.
    143     // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
    144     const int ALLOCFRAME_MAX = 16384;
    145     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    146 
    147     if (NumBytes >= ALLOCFRAME_MAX) {
    148       // Emit allocframe(#0).
    149       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
    150 
    151       // Subtract offset from frame pointer.
    152       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
    153                                       HEXAGON_RESERVED_REG_1).addImm(NumBytes);
    154       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
    155                                       QRI->getStackRegister()).
    156                                       addReg(QRI->getStackRegister()).
    157                                       addReg(HEXAGON_RESERVED_REG_1);
    158     } else {
    159       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
    160     }
    161   }
    162 }
    163 // Returns true if MBB has a machine instructions that indicates a tail call
    164 // in the block.
    165 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
    166   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    167   unsigned RetOpcode = MBBI->getOpcode();
    168 
    169   return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;}
    170 
    171 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
    172                                      MachineBasicBlock &MBB) const {
    173   MachineBasicBlock::iterator MBBI = prior(MBB.end());
    174   DebugLoc dl = MBBI->getDebugLoc();
    175   //
    176   // Only insert deallocframe if we need to.
    177   //
    178   if (hasFP(MF)) {
    179     MachineBasicBlock::iterator MBBI = prior(MBB.end());
    180     MachineBasicBlock::iterator MBBI_end = MBB.end();
    181     //
    182     // For Hexagon, we don't need the frame size.
    183     //
    184     MachineFrameInfo *MFI = MF.getFrameInfo();
    185     int NumBytes = (int) MFI->getStackSize();
    186 
    187     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    188 
    189     // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
    190     // versions.
    191     if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR
    192                         && !DisableDeallocRet) {
    193       // Remove jumpr node.
    194       MBB.erase(MBBI);
    195       // Add dealloc_return.
    196       BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4))
    197         .addImm(NumBytes);
    198     } else { // Add deallocframe for V2 and V3.
    199       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes);
    200     }
    201   }
    202 }
    203 
    204 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
    205   const MachineFrameInfo *MFI = MF.getFrameInfo();
    206   const HexagonMachineFunctionInfo *FuncInfo =
    207     MF.getInfo<HexagonMachineFunctionInfo>();
    208   return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
    209           FuncInfo->hasClobberLR() );
    210 }
    211 
    212 bool
    213 HexagonFrameLowering::spillCalleeSavedRegisters(
    214                                         MachineBasicBlock &MBB,
    215                                         MachineBasicBlock::iterator MI,
    216                                         const std::vector<CalleeSavedInfo> &CSI,
    217                                         const TargetRegisterInfo *TRI) const {
    218   MachineFunction *MF = MBB.getParent();
    219   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
    220 
    221   if (CSI.empty()) {
    222     return false;
    223   }
    224 
    225   // We can only schedule double loads if we spill contiguous callee-saved regs
    226   // For instance, we cannot scheduled double-word loads if we spill r24,
    227   // r26, and r27.
    228   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
    229   // above.
    230   bool ContiguousRegs = true;
    231 
    232   for (unsigned i = 0; i < CSI.size(); ++i) {
    233     unsigned Reg = CSI[i].getReg();
    234 
    235     //
    236     // Check if we can use a double-word store.
    237     //
    238     const uint16_t* SuperReg = TRI->getSuperRegisters(Reg);
    239 
    240     // Assume that there is exactly one superreg.
    241     assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg");
    242     bool CanUseDblStore = false;
    243     const TargetRegisterClass* SuperRegClass = 0;
    244 
    245     if (ContiguousRegs && (i < CSI.size()-1)) {
    246       const uint16_t* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg());
    247       assert(SuperRegNext[0] && !SuperRegNext[1] &&
    248              "Expected exactly one superreg");
    249       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]);
    250       CanUseDblStore = (SuperRegNext[0] == SuperReg[0]);
    251     }
    252 
    253 
    254     if (CanUseDblStore) {
    255       TII.storeRegToStackSlot(MBB, MI, SuperReg[0], true,
    256                               CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
    257       MBB.addLiveIn(SuperReg[0]);
    258       ++i;
    259     } else {
    260       // Cannot use a double-word store.
    261       ContiguousRegs = false;
    262       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    263       TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
    264                               TRI);
    265       MBB.addLiveIn(Reg);
    266     }
    267   }
    268   return true;
    269 }
    270 
    271 
    272 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
    273                                         MachineBasicBlock &MBB,
    274                                         MachineBasicBlock::iterator MI,
    275                                         const std::vector<CalleeSavedInfo> &CSI,
    276                                         const TargetRegisterInfo *TRI) const {
    277 
    278   MachineFunction *MF = MBB.getParent();
    279   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
    280 
    281   if (CSI.empty()) {
    282     return false;
    283   }
    284 
    285   // We can only schedule double loads if we spill contiguous callee-saved regs
    286   // For instance, we cannot scheduled double-word loads if we spill r24,
    287   // r26, and r27.
    288   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
    289   // above.
    290   bool ContiguousRegs = true;
    291 
    292   for (unsigned i = 0; i < CSI.size(); ++i) {
    293     unsigned Reg = CSI[i].getReg();
    294 
    295     //
    296     // Check if we can use a double-word load.
    297     //
    298     const uint16_t* SuperReg = TRI->getSuperRegisters(Reg);
    299     const TargetRegisterClass* SuperRegClass = 0;
    300 
    301     // Assume that there is exactly one superreg.
    302     assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg");
    303     bool CanUseDblLoad = false;
    304     if (ContiguousRegs && (i < CSI.size()-1)) {
    305       const uint16_t* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg());
    306       assert(SuperRegNext[0] && !SuperRegNext[1] &&
    307              "Expected exactly one superreg");
    308       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]);
    309       CanUseDblLoad = (SuperRegNext[0] == SuperReg[0]);
    310     }
    311 
    312 
    313     if (CanUseDblLoad) {
    314       TII.loadRegFromStackSlot(MBB, MI, SuperReg[0], CSI[i+1].getFrameIdx(),
    315                                SuperRegClass, TRI);
    316       MBB.addLiveIn(SuperReg[0]);
    317       ++i;
    318     } else {
    319       // Cannot use a double-word load.
    320       ContiguousRegs = false;
    321       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    322       TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
    323       MBB.addLiveIn(Reg);
    324     }
    325   }
    326   return true;
    327 }
    328 
    329 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
    330                                               int FI) const {
    331   return MF.getFrameInfo()->getObjectOffset(FI);
    332 }
    333