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