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 = prior(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 = prior(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 (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret 169 && !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 : prior(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() : prior(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 = 0; 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 = 0; 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