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 "HexagonMachineFunctionInfo.h"
     15 #include "HexagonRegisterInfo.h"
     16 #include "HexagonSubtarget.h"
     17 #include "HexagonTargetMachine.h"
     18 #include "llvm/ADT/BitVector.h"
     19 #include "llvm/ADT/STLExtras.h"
     20 #include "llvm/CodeGen/AsmPrinter.h"
     21 #include "llvm/CodeGen/MachineFrameInfo.h"
     22 #include "llvm/CodeGen/MachineFunction.h"
     23 #include "llvm/CodeGen/MachineFunctionPass.h"
     24 #include "llvm/CodeGen/MachineInstrBuilder.h"
     25 #include "llvm/CodeGen/MachineModuleInfo.h"
     26 #include "llvm/CodeGen/MachineRegisterInfo.h"
     27 #include "llvm/CodeGen/RegisterScavenging.h"
     28 #include "llvm/IR/Function.h"
     29 #include "llvm/IR/Type.h"
     30 #include "llvm/MC/MCAsmInfo.h"
     31 #include "llvm/MC/MachineLocation.h"
     32 #include "llvm/Support/CommandLine.h"
     33 #include "llvm/Target/TargetInstrInfo.h"
     34 #include "llvm/Target/TargetMachine.h"
     35 #include "llvm/Target/TargetOptions.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   MachineBasicBlock::iterator MBBI = MBB.begin();
     80   const HexagonRegisterInfo *QRI =
     81     static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
     82   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
     83   determineFrameLayout(MF);
     84 
     85   // Get the number of bytes to allocate from the FrameInfo.
     86   int NumBytes = (int) MFI->getStackSize();
     87 
     88   // LLVM expects allocframe not to be the first instruction in the
     89   // basic block.
     90   MachineBasicBlock::iterator InsertPt = MBB.begin();
     91 
     92   //
     93   // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
     94   //
     95   HexagonMachineFunctionInfo *FuncInfo =
     96     MF.getInfo<HexagonMachineFunctionInfo>();
     97   const std::vector<MachineInstr*>& AdjustRegs =
     98     FuncInfo->getAllocaAdjustInsts();
     99   for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
    100          e = AdjustRegs.end();
    101        i != e; ++i) {
    102     MachineInstr* MI = *i;
    103     assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
    104            "Expected adjust alloca node");
    105 
    106     MachineOperand& MO = MI->getOperand(2);
    107     assert(MO.isImm() && "Expected immediate");
    108     MO.setImm(MFI->getMaxCallFrameSize());
    109   }
    110 
    111   //
    112   // Only insert ALLOCFRAME if we need to.
    113   //
    114   if (hasFP(MF)) {
    115     // Check for overflow.
    116     // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
    117     const int ALLOCFRAME_MAX = 16384;
    118     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    119 
    120     if (NumBytes >= ALLOCFRAME_MAX) {
    121       // Emit allocframe(#0).
    122       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
    123 
    124       // Subtract offset from frame pointer.
    125       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
    126                                       HEXAGON_RESERVED_REG_1).addImm(NumBytes);
    127       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
    128                                       QRI->getStackRegister()).
    129                                       addReg(QRI->getStackRegister()).
    130                                       addReg(HEXAGON_RESERVED_REG_1);
    131     } else {
    132       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
    133     }
    134   }
    135 }
    136 // Returns true if MBB has a machine instructions that indicates a tail call
    137 // in the block.
    138 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
    139   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    140   unsigned RetOpcode = MBBI->getOpcode();
    141 
    142   return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
    143 }
    144 
    145 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
    146                                      MachineBasicBlock &MBB) const {
    147   MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
    148   DebugLoc dl = MBBI->getDebugLoc();
    149   //
    150   // Only insert deallocframe if we need to.  Also at -O0.  See comment
    151   // in emitPrologue above.
    152   //
    153   if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
    154     MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
    155     MachineBasicBlock::iterator MBBI_end = MBB.end();
    156 
    157     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    158     // Handle EH_RETURN.
    159     if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
    160       assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
    161       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
    162       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
    163               Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
    164       return;
    165     }
    166     // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
    167     // versions.
    168     if (MF.getTarget().getSubtarget<HexagonSubtarget>().hasV4TOps() &&
    169         MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
    170       // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
    171       // instruction if we encounter it.
    172       MachineBasicBlock::iterator BeforeJMPR =
    173         MBB.begin() == MBBI ? MBBI : std::prev(MBBI);
    174       if (BeforeJMPR != MBBI &&
    175           BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
    176         // Remove the JMPR node.
    177         MBB.erase(MBBI);
    178         return;
    179       }
    180 
    181       // Add dealloc_return.
    182       MachineInstrBuilder MIB =
    183         BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
    184       // Transfer the function live-out registers.
    185       MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
    186       // Remove the JUMPR node.
    187       MBB.erase(MBBI);
    188     } else { // Add deallocframe for V2 and V3, and V4 tail calls.
    189       // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
    190       // DEALLOCFRAME instruction after it.
    191       MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
    192       MachineBasicBlock::iterator I =
    193         Term == MBB.begin() ?  MBB.end() : std::prev(Term);
    194       if (I != MBB.end() &&
    195           I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
    196         return;
    197 
    198       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
    199     }
    200   }
    201 }
    202 
    203 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
    204   const MachineFrameInfo *MFI = MF.getFrameInfo();
    205   const HexagonMachineFunctionInfo *FuncInfo =
    206     MF.getInfo<HexagonMachineFunctionInfo>();
    207   return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
    208           FuncInfo->hasClobberLR() );
    209 }
    210 
    211 static inline
    212 unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
    213   MCSuperRegIterator SRI(Reg, TRI);
    214   assert(SRI.isValid() && "Expected a superreg");
    215   unsigned SuperReg = *SRI;
    216   ++SRI;
    217   assert(!SRI.isValid() && "Expected exactly one superreg");
    218   return SuperReg;
    219 }
    220 
    221 bool
    222 HexagonFrameLowering::spillCalleeSavedRegisters(
    223                                         MachineBasicBlock &MBB,
    224                                         MachineBasicBlock::iterator MI,
    225                                         const std::vector<CalleeSavedInfo> &CSI,
    226                                         const TargetRegisterInfo *TRI) const {
    227   MachineFunction *MF = MBB.getParent();
    228   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
    229 
    230   if (CSI.empty()) {
    231     return false;
    232   }
    233 
    234   // We can only schedule double loads if we spill contiguous callee-saved regs
    235   // For instance, we cannot scheduled double-word loads if we spill r24,
    236   // r26, and r27.
    237   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
    238   // above.
    239   bool ContiguousRegs = true;
    240 
    241   for (unsigned i = 0; i < CSI.size(); ++i) {
    242     unsigned Reg = CSI[i].getReg();
    243 
    244     //
    245     // Check if we can use a double-word store.
    246     //
    247     unsigned SuperReg = uniqueSuperReg(Reg, TRI);
    248     bool CanUseDblStore = false;
    249     const TargetRegisterClass* SuperRegClass = nullptr;
    250 
    251     if (ContiguousRegs && (i < CSI.size()-1)) {
    252       unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
    253       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
    254       CanUseDblStore = (SuperRegNext == SuperReg);
    255     }
    256 
    257 
    258     if (CanUseDblStore) {
    259       TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
    260                               CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
    261       MBB.addLiveIn(SuperReg);
    262       ++i;
    263     } else {
    264       // Cannot use a double-word store.
    265       ContiguousRegs = false;
    266       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    267       TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
    268                               TRI);
    269       MBB.addLiveIn(Reg);
    270     }
    271   }
    272   return true;
    273 }
    274 
    275 
    276 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
    277                                         MachineBasicBlock &MBB,
    278                                         MachineBasicBlock::iterator MI,
    279                                         const std::vector<CalleeSavedInfo> &CSI,
    280                                         const TargetRegisterInfo *TRI) const {
    281 
    282   MachineFunction *MF = MBB.getParent();
    283   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
    284 
    285   if (CSI.empty()) {
    286     return false;
    287   }
    288 
    289   // We can only schedule double loads if we spill contiguous callee-saved regs
    290   // For instance, we cannot scheduled double-word loads if we spill r24,
    291   // r26, and r27.
    292   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
    293   // above.
    294   bool ContiguousRegs = true;
    295 
    296   for (unsigned i = 0; i < CSI.size(); ++i) {
    297     unsigned Reg = CSI[i].getReg();
    298 
    299     //
    300     // Check if we can use a double-word load.
    301     //
    302     unsigned SuperReg = uniqueSuperReg(Reg, TRI);
    303     const TargetRegisterClass* SuperRegClass = nullptr;
    304     bool CanUseDblLoad = false;
    305     if (ContiguousRegs && (i < CSI.size()-1)) {
    306       unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
    307       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
    308       CanUseDblLoad = (SuperRegNext == SuperReg);
    309     }
    310 
    311 
    312     if (CanUseDblLoad) {
    313       TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
    314                                SuperRegClass, TRI);
    315       MBB.addLiveIn(SuperReg);
    316       ++i;
    317     } else {
    318       // Cannot use a double-word load.
    319       ContiguousRegs = false;
    320       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    321       TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
    322       MBB.addLiveIn(Reg);
    323     }
    324   }
    325   return true;
    326 }
    327 
    328 void HexagonFrameLowering::
    329 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
    330                               MachineBasicBlock::iterator I) const {
    331   MachineInstr &MI = *I;
    332 
    333   if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
    334     // Hexagon_TODO: add code
    335   } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
    336     // Hexagon_TODO: add code
    337   } else {
    338     llvm_unreachable("Cannot handle this call frame pseudo instruction");
    339   }
    340   MBB.erase(I);
    341 }
    342 
    343 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
    344                                               int FI) const {
    345   return MF.getFrameInfo()->getObjectOffset(FI);
    346 }
    347