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 37using namespace llvm; 38 39static 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. 46void 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 76void 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. 165bool 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 172void HexagonFrameLowering::emitEpilogue(MachineFunction &MF, 173 MachineBasicBlock &MBB) const { 174 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 175 DebugLoc dl = MBBI->getDebugLoc(); 176 // 177 // Only insert deallocframe if we need to. 178 // 179 if (hasFP(MF)) { 180 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 181 MachineBasicBlock::iterator MBBI_end = MBB.end(); 182 // 183 // For Hexagon, we don't need the frame size. 184 // 185 MachineFrameInfo *MFI = MF.getFrameInfo(); 186 int NumBytes = (int) MFI->getStackSize(); 187 188 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 189 190 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher 191 // versions. 192 if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR 193 && !DisableDeallocRet) { 194 // Remove jumpr node. 195 MBB.erase(MBBI); 196 // Add dealloc_return. 197 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)) 198 .addImm(NumBytes); 199 } else { // Add deallocframe for V2 and V3. 200 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes); 201 } 202 } 203} 204 205bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { 206 const MachineFrameInfo *MFI = MF.getFrameInfo(); 207 const HexagonMachineFunctionInfo *FuncInfo = 208 MF.getInfo<HexagonMachineFunctionInfo>(); 209 return (MFI->hasCalls() || (MFI->getStackSize() > 0) || 210 FuncInfo->hasClobberLR() ); 211} 212 213static inline 214unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) { 215 MCSuperRegIterator SRI(Reg, TRI); 216 assert(SRI.isValid() && "Expected a superreg"); 217 unsigned SuperReg = *SRI; 218 ++SRI; 219 assert(!SRI.isValid() && "Expected exactly one superreg"); 220 return SuperReg; 221} 222 223bool 224HexagonFrameLowering::spillCalleeSavedRegisters( 225 MachineBasicBlock &MBB, 226 MachineBasicBlock::iterator MI, 227 const std::vector<CalleeSavedInfo> &CSI, 228 const TargetRegisterInfo *TRI) const { 229 MachineFunction *MF = MBB.getParent(); 230 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 231 232 if (CSI.empty()) { 233 return false; 234 } 235 236 // We can only schedule double loads if we spill contiguous callee-saved regs 237 // For instance, we cannot scheduled double-word loads if we spill r24, 238 // r26, and r27. 239 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 240 // above. 241 bool ContiguousRegs = true; 242 243 for (unsigned i = 0; i < CSI.size(); ++i) { 244 unsigned Reg = CSI[i].getReg(); 245 246 // 247 // Check if we can use a double-word store. 248 // 249 unsigned SuperReg = uniqueSuperReg(Reg, TRI); 250 bool CanUseDblStore = false; 251 const TargetRegisterClass* SuperRegClass = 0; 252 253 if (ContiguousRegs && (i < CSI.size()-1)) { 254 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 255 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 256 CanUseDblStore = (SuperRegNext == SuperReg); 257 } 258 259 260 if (CanUseDblStore) { 261 TII.storeRegToStackSlot(MBB, MI, SuperReg, true, 262 CSI[i+1].getFrameIdx(), SuperRegClass, TRI); 263 MBB.addLiveIn(SuperReg); 264 ++i; 265 } else { 266 // Cannot use a double-word store. 267 ContiguousRegs = false; 268 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 269 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC, 270 TRI); 271 MBB.addLiveIn(Reg); 272 } 273 } 274 return true; 275} 276 277 278bool HexagonFrameLowering::restoreCalleeSavedRegisters( 279 MachineBasicBlock &MBB, 280 MachineBasicBlock::iterator MI, 281 const std::vector<CalleeSavedInfo> &CSI, 282 const TargetRegisterInfo *TRI) const { 283 284 MachineFunction *MF = MBB.getParent(); 285 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 286 287 if (CSI.empty()) { 288 return false; 289 } 290 291 // We can only schedule double loads if we spill contiguous callee-saved regs 292 // For instance, we cannot scheduled double-word loads if we spill r24, 293 // r26, and r27. 294 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 295 // above. 296 bool ContiguousRegs = true; 297 298 for (unsigned i = 0; i < CSI.size(); ++i) { 299 unsigned Reg = CSI[i].getReg(); 300 301 // 302 // Check if we can use a double-word load. 303 // 304 unsigned SuperReg = uniqueSuperReg(Reg, TRI); 305 const TargetRegisterClass* SuperRegClass = 0; 306 bool CanUseDblLoad = false; 307 if (ContiguousRegs && (i < CSI.size()-1)) { 308 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 309 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 310 CanUseDblLoad = (SuperRegNext == SuperReg); 311 } 312 313 314 if (CanUseDblLoad) { 315 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(), 316 SuperRegClass, TRI); 317 MBB.addLiveIn(SuperReg); 318 ++i; 319 } else { 320 // Cannot use a double-word load. 321 ContiguousRegs = false; 322 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 323 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI); 324 MBB.addLiveIn(Reg); 325 } 326 } 327 return true; 328} 329 330void HexagonFrameLowering:: 331eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 332 MachineBasicBlock::iterator I) const { 333 MachineInstr &MI = *I; 334 335 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { 336 // Hexagon_TODO: add code 337 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { 338 // Hexagon_TODO: add code 339 } else { 340 llvm_unreachable("Cannot handle this call frame pseudo instruction"); 341 } 342 MBB.erase(I); 343} 344 345int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 346 int FI) const { 347 return MF.getFrameInfo()->getObjectOffset(FI); 348} 349