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