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