LLVM API Documentation
00001 //===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 // 00009 //===----------------------------------------------------------------------===// 00010 00011 #include "HexagonFrameLowering.h" 00012 #include "Hexagon.h" 00013 #include "HexagonInstrInfo.h" 00014 #include "HexagonMachineFunctionInfo.h" 00015 #include "HexagonRegisterInfo.h" 00016 #include "HexagonSubtarget.h" 00017 #include "HexagonTargetMachine.h" 00018 #include "llvm/ADT/BitVector.h" 00019 #include "llvm/ADT/STLExtras.h" 00020 #include "llvm/CodeGen/AsmPrinter.h" 00021 #include "llvm/CodeGen/MachineFrameInfo.h" 00022 #include "llvm/CodeGen/MachineFunction.h" 00023 #include "llvm/CodeGen/MachineFunctionPass.h" 00024 #include "llvm/CodeGen/MachineInstrBuilder.h" 00025 #include "llvm/CodeGen/MachineModuleInfo.h" 00026 #include "llvm/CodeGen/MachineRegisterInfo.h" 00027 #include "llvm/CodeGen/RegisterScavenging.h" 00028 #include "llvm/IR/Function.h" 00029 #include "llvm/IR/Type.h" 00030 #include "llvm/MC/MCAsmInfo.h" 00031 #include "llvm/MC/MachineLocation.h" 00032 #include "llvm/Support/CommandLine.h" 00033 #include "llvm/Target/TargetInstrInfo.h" 00034 #include "llvm/Target/TargetMachine.h" 00035 #include "llvm/Target/TargetOptions.h" 00036 00037 using namespace llvm; 00038 00039 static cl::opt<bool> DisableDeallocRet( 00040 "disable-hexagon-dealloc-ret", 00041 cl::Hidden, 00042 cl::desc("Disable Dealloc Return for Hexagon target")); 00043 00044 /// determineFrameLayout - Determine the size of the frame and maximum call 00045 /// frame size. 00046 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const { 00047 MachineFrameInfo *MFI = MF.getFrameInfo(); 00048 00049 // Get the number of bytes to allocate from the FrameInfo. 00050 unsigned FrameSize = MFI->getStackSize(); 00051 00052 // Get the alignments provided by the target. 00053 unsigned TargetAlign = MF.getTarget() 00054 .getSubtargetImpl() 00055 ->getFrameLowering() 00056 ->getStackAlignment(); 00057 // Get the maximum call frame size of all the calls. 00058 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 00059 00060 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 00061 // that allocations will be aligned. 00062 if (MFI->hasVarSizedObjects()) 00063 maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign); 00064 00065 // Update maximum call frame size. 00066 MFI->setMaxCallFrameSize(maxCallFrameSize); 00067 00068 // Include call frame size in total. 00069 FrameSize += maxCallFrameSize; 00070 00071 // Make sure the frame is aligned. 00072 FrameSize = RoundUpToAlignment(FrameSize, TargetAlign); 00073 00074 // Update frame info. 00075 MFI->setStackSize(FrameSize); 00076 } 00077 00078 00079 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { 00080 MachineBasicBlock &MBB = MF.front(); 00081 MachineFrameInfo *MFI = MF.getFrameInfo(); 00082 MachineBasicBlock::iterator MBBI = MBB.begin(); 00083 const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>( 00084 MF.getSubtarget().getRegisterInfo()); 00085 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 00086 determineFrameLayout(MF); 00087 00088 // Get the number of bytes to allocate from the FrameInfo. 00089 int NumBytes = (int) MFI->getStackSize(); 00090 00091 // LLVM expects allocframe not to be the first instruction in the 00092 // basic block. 00093 MachineBasicBlock::iterator InsertPt = MBB.begin(); 00094 00095 // 00096 // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset. 00097 // 00098 HexagonMachineFunctionInfo *FuncInfo = 00099 MF.getInfo<HexagonMachineFunctionInfo>(); 00100 const std::vector<MachineInstr*>& AdjustRegs = 00101 FuncInfo->getAllocaAdjustInsts(); 00102 for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(), 00103 e = AdjustRegs.end(); 00104 i != e; ++i) { 00105 MachineInstr* MI = *i; 00106 assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) && 00107 "Expected adjust alloca node"); 00108 00109 MachineOperand& MO = MI->getOperand(2); 00110 assert(MO.isImm() && "Expected immediate"); 00111 MO.setImm(MFI->getMaxCallFrameSize()); 00112 } 00113 00114 // 00115 // Only insert ALLOCFRAME if we need to. 00116 // 00117 if (hasFP(MF)) { 00118 // Check for overflow. 00119 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? 00120 const int ALLOCFRAME_MAX = 16384; 00121 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 00122 00123 if (NumBytes >= ALLOCFRAME_MAX) { 00124 // Emit allocframe(#0). 00125 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0); 00126 00127 // Subtract offset from frame pointer. 00128 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), 00129 HEXAGON_RESERVED_REG_1).addImm(NumBytes); 00130 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr), 00131 QRI->getStackRegister()). 00132 addReg(QRI->getStackRegister()). 00133 addReg(HEXAGON_RESERVED_REG_1); 00134 } else { 00135 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes); 00136 } 00137 } 00138 } 00139 // Returns true if MBB has a machine instructions that indicates a tail call 00140 // in the block. 00141 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const { 00142 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 00143 unsigned RetOpcode = MBBI->getOpcode(); 00144 00145 return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext; 00146 } 00147 00148 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF, 00149 MachineBasicBlock &MBB) const { 00150 MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); 00151 DebugLoc dl = MBBI->getDebugLoc(); 00152 // 00153 // Only insert deallocframe if we need to. Also at -O0. See comment 00154 // in emitPrologue above. 00155 // 00156 if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) { 00157 MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); 00158 MachineBasicBlock::iterator MBBI_end = MBB.end(); 00159 00160 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 00161 // Handle EH_RETURN. 00162 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) { 00163 assert(MBBI->getOperand(0).isReg() && "Offset should be in register!"); 00164 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); 00165 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr), 00166 Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28); 00167 return; 00168 } 00169 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher 00170 // versions. 00171 if (MF.getTarget().getSubtarget<HexagonSubtarget>().hasV4TOps() && 00172 MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) { 00173 // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC 00174 // instruction if we encounter it. 00175 MachineBasicBlock::iterator BeforeJMPR = 00176 MBB.begin() == MBBI ? MBBI : std::prev(MBBI); 00177 if (BeforeJMPR != MBBI && 00178 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) { 00179 // Remove the JMPR node. 00180 MBB.erase(MBBI); 00181 return; 00182 } 00183 00184 // Add dealloc_return. 00185 MachineInstrBuilder MIB = 00186 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)); 00187 // Transfer the function live-out registers. 00188 MIB->copyImplicitOps(*MBB.getParent(), &*MBBI); 00189 // Remove the JUMPR node. 00190 MBB.erase(MBBI); 00191 } else { // Add deallocframe for V2 and V3, and V4 tail calls. 00192 // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra 00193 // DEALLOCFRAME instruction after it. 00194 MachineBasicBlock::iterator Term = MBB.getFirstTerminator(); 00195 MachineBasicBlock::iterator I = 00196 Term == MBB.begin() ? MBB.end() : std::prev(Term); 00197 if (I != MBB.end() && 00198 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4) 00199 return; 00200 00201 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); 00202 } 00203 } 00204 } 00205 00206 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { 00207 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00208 const HexagonMachineFunctionInfo *FuncInfo = 00209 MF.getInfo<HexagonMachineFunctionInfo>(); 00210 return (MFI->hasCalls() || (MFI->getStackSize() > 0) || 00211 FuncInfo->hasClobberLR() ); 00212 } 00213 00214 static inline 00215 unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) { 00216 MCSuperRegIterator SRI(Reg, TRI); 00217 assert(SRI.isValid() && "Expected a superreg"); 00218 unsigned SuperReg = *SRI; 00219 ++SRI; 00220 assert(!SRI.isValid() && "Expected exactly one superreg"); 00221 return SuperReg; 00222 } 00223 00224 bool 00225 HexagonFrameLowering::spillCalleeSavedRegisters( 00226 MachineBasicBlock &MBB, 00227 MachineBasicBlock::iterator MI, 00228 const std::vector<CalleeSavedInfo> &CSI, 00229 const TargetRegisterInfo *TRI) const { 00230 MachineFunction *MF = MBB.getParent(); 00231 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 00232 00233 if (CSI.empty()) { 00234 return false; 00235 } 00236 00237 // We can only schedule double loads if we spill contiguous callee-saved regs 00238 // For instance, we cannot scheduled double-word loads if we spill r24, 00239 // r26, and r27. 00240 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 00241 // above. 00242 bool ContiguousRegs = true; 00243 00244 for (unsigned i = 0; i < CSI.size(); ++i) { 00245 unsigned Reg = CSI[i].getReg(); 00246 00247 // 00248 // Check if we can use a double-word store. 00249 // 00250 unsigned SuperReg = uniqueSuperReg(Reg, TRI); 00251 bool CanUseDblStore = false; 00252 const TargetRegisterClass* SuperRegClass = nullptr; 00253 00254 if (ContiguousRegs && (i < CSI.size()-1)) { 00255 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 00256 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 00257 CanUseDblStore = (SuperRegNext == SuperReg); 00258 } 00259 00260 00261 if (CanUseDblStore) { 00262 TII.storeRegToStackSlot(MBB, MI, SuperReg, true, 00263 CSI[i+1].getFrameIdx(), SuperRegClass, TRI); 00264 MBB.addLiveIn(SuperReg); 00265 ++i; 00266 } else { 00267 // Cannot use a double-word store. 00268 ContiguousRegs = false; 00269 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 00270 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC, 00271 TRI); 00272 MBB.addLiveIn(Reg); 00273 } 00274 } 00275 return true; 00276 } 00277 00278 00279 bool HexagonFrameLowering::restoreCalleeSavedRegisters( 00280 MachineBasicBlock &MBB, 00281 MachineBasicBlock::iterator MI, 00282 const std::vector<CalleeSavedInfo> &CSI, 00283 const TargetRegisterInfo *TRI) const { 00284 00285 MachineFunction *MF = MBB.getParent(); 00286 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 00287 00288 if (CSI.empty()) { 00289 return false; 00290 } 00291 00292 // We can only schedule double loads if we spill contiguous callee-saved regs 00293 // For instance, we cannot scheduled double-word loads if we spill r24, 00294 // r26, and r27. 00295 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 00296 // above. 00297 bool ContiguousRegs = true; 00298 00299 for (unsigned i = 0; i < CSI.size(); ++i) { 00300 unsigned Reg = CSI[i].getReg(); 00301 00302 // 00303 // Check if we can use a double-word load. 00304 // 00305 unsigned SuperReg = uniqueSuperReg(Reg, TRI); 00306 const TargetRegisterClass* SuperRegClass = nullptr; 00307 bool CanUseDblLoad = false; 00308 if (ContiguousRegs && (i < CSI.size()-1)) { 00309 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 00310 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 00311 CanUseDblLoad = (SuperRegNext == SuperReg); 00312 } 00313 00314 00315 if (CanUseDblLoad) { 00316 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(), 00317 SuperRegClass, TRI); 00318 MBB.addLiveIn(SuperReg); 00319 ++i; 00320 } else { 00321 // Cannot use a double-word load. 00322 ContiguousRegs = false; 00323 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 00324 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI); 00325 MBB.addLiveIn(Reg); 00326 } 00327 } 00328 return true; 00329 } 00330 00331 void HexagonFrameLowering:: 00332 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00333 MachineBasicBlock::iterator I) const { 00334 MachineInstr &MI = *I; 00335 00336 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { 00337 // Hexagon_TODO: add code 00338 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { 00339 // Hexagon_TODO: add code 00340 } else { 00341 llvm_unreachable("Cannot handle this call frame pseudo instruction"); 00342 } 00343 MBB.erase(I); 00344 } 00345 00346 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 00347 int FI) const { 00348 return MF.getFrameInfo()->getObjectOffset(FI); 00349 }