LLVM API Documentation
00001 //===-- Thumb1FrameLowering.cpp - Thumb1 Frame Information ----------------===// 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 // This file contains the Thumb1 implementation of TargetFrameLowering class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Thumb1FrameLowering.h" 00015 #include "ARMMachineFunctionInfo.h" 00016 #include "llvm/CodeGen/MachineFrameInfo.h" 00017 #include "llvm/CodeGen/MachineFunction.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 #include "llvm/CodeGen/MachineRegisterInfo.h" 00020 00021 using namespace llvm; 00022 00023 bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{ 00024 const MachineFrameInfo *FFI = MF.getFrameInfo(); 00025 unsigned CFSize = FFI->getMaxCallFrameSize(); 00026 // It's not always a good idea to include the call frame as part of the 00027 // stack frame. ARM (especially Thumb) has small immediate offset to 00028 // address the stack frame. So a large call frame can cause poor codegen 00029 // and may even makes it impossible to scavenge a register. 00030 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 00031 return false; 00032 00033 return !MF.getFrameInfo()->hasVarSizedObjects(); 00034 } 00035 00036 static void 00037 emitSPUpdate(MachineBasicBlock &MBB, 00038 MachineBasicBlock::iterator &MBBI, 00039 const TargetInstrInfo &TII, DebugLoc dl, 00040 const Thumb1RegisterInfo &MRI, 00041 int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) { 00042 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII, 00043 MRI, MIFlags); 00044 } 00045 00046 00047 void Thumb1FrameLowering:: 00048 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00049 MachineBasicBlock::iterator I) const { 00050 const Thumb1InstrInfo &TII = 00051 *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 00052 const Thumb1RegisterInfo *RegInfo = 00053 static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 00054 if (!hasReservedCallFrame(MF)) { 00055 // If we have alloca, convert as follows: 00056 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 00057 // ADJCALLSTACKUP -> add, sp, sp, amount 00058 MachineInstr *Old = I; 00059 DebugLoc dl = Old->getDebugLoc(); 00060 unsigned Amount = Old->getOperand(0).getImm(); 00061 if (Amount != 0) { 00062 // We need to keep the stack aligned properly. To do this, we round the 00063 // amount of space needed for the outgoing arguments up to the next 00064 // alignment boundary. 00065 unsigned Align = getStackAlignment(); 00066 Amount = (Amount+Align-1)/Align*Align; 00067 00068 // Replace the pseudo instruction with a new instruction... 00069 unsigned Opc = Old->getOpcode(); 00070 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 00071 emitSPUpdate(MBB, I, TII, dl, *RegInfo, -Amount); 00072 } else { 00073 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 00074 emitSPUpdate(MBB, I, TII, dl, *RegInfo, Amount); 00075 } 00076 } 00077 } 00078 MBB.erase(I); 00079 } 00080 00081 void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { 00082 MachineBasicBlock &MBB = MF.front(); 00083 MachineBasicBlock::iterator MBBI = MBB.begin(); 00084 MachineFrameInfo *MFI = MF.getFrameInfo(); 00085 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00086 const Thumb1RegisterInfo *RegInfo = 00087 static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 00088 const Thumb1InstrInfo &TII = 00089 *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 00090 00091 unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); 00092 unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); 00093 unsigned NumBytes = MFI->getStackSize(); 00094 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 00095 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 00096 unsigned FramePtr = RegInfo->getFrameRegister(MF); 00097 unsigned BasePtr = RegInfo->getBaseRegister(); 00098 00099 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 00100 NumBytes = (NumBytes + 3) & ~3; 00101 MFI->setStackSize(NumBytes); 00102 00103 // Determine the sizes of each callee-save spill areas and record which frame 00104 // belongs to which callee-save spill areas. 00105 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 00106 int FramePtrSpillFI = 0; 00107 00108 if (ArgRegsSaveSize) 00109 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize, 00110 MachineInstr::FrameSetup); 00111 00112 if (!AFI->hasStackFrame()) { 00113 if (NumBytes != 0) 00114 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, 00115 MachineInstr::FrameSetup); 00116 return; 00117 } 00118 00119 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 00120 unsigned Reg = CSI[i].getReg(); 00121 int FI = CSI[i].getFrameIdx(); 00122 switch (Reg) { 00123 case ARM::R4: 00124 case ARM::R5: 00125 case ARM::R6: 00126 case ARM::R7: 00127 case ARM::LR: 00128 if (Reg == FramePtr) 00129 FramePtrSpillFI = FI; 00130 AFI->addGPRCalleeSavedArea1Frame(FI); 00131 GPRCS1Size += 4; 00132 break; 00133 case ARM::R8: 00134 case ARM::R9: 00135 case ARM::R10: 00136 case ARM::R11: 00137 if (Reg == FramePtr) 00138 FramePtrSpillFI = FI; 00139 if (STI.isTargetIOS()) { 00140 AFI->addGPRCalleeSavedArea2Frame(FI); 00141 GPRCS2Size += 4; 00142 } else { 00143 AFI->addGPRCalleeSavedArea1Frame(FI); 00144 GPRCS1Size += 4; 00145 } 00146 break; 00147 default: 00148 AFI->addDPRCalleeSavedAreaFrame(FI); 00149 DPRCSSize += 8; 00150 } 00151 } 00152 00153 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { 00154 ++MBBI; 00155 if (MBBI != MBB.end()) 00156 dl = MBBI->getDebugLoc(); 00157 } 00158 00159 // Determine starting offsets of spill areas. 00160 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 00161 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 00162 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 00163 bool HasFP = hasFP(MF); 00164 if (HasFP) 00165 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + 00166 NumBytes); 00167 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 00168 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 00169 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 00170 NumBytes = DPRCSOffset; 00171 00172 // Adjust FP so it point to the stack slot that contains the previous FP. 00173 if (HasFP) { 00174 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) 00175 .addFrameIndex(FramePtrSpillFI).addImm(0) 00176 .setMIFlags(MachineInstr::FrameSetup)); 00177 if (NumBytes > 508) 00178 // If offset is > 508 then sp cannot be adjusted in a single instruction, 00179 // try restoring from fp instead. 00180 AFI->setShouldRestoreSPFromFP(true); 00181 } 00182 00183 if (NumBytes) 00184 // Insert it after all the callee-save spills. 00185 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, 00186 MachineInstr::FrameSetup); 00187 00188 if (STI.isTargetELF() && HasFP) 00189 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 00190 AFI->getFramePtrSpillOffset()); 00191 00192 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 00193 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 00194 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 00195 00196 // Thumb1 does not currently support dynamic stack realignment. Report a 00197 // fatal error rather then silently generate bad code. 00198 if (RegInfo->needsStackRealignment(MF)) 00199 report_fatal_error("Dynamic stack realignment not supported for thumb1."); 00200 00201 // If we need a base pointer, set it up here. It's whatever the value 00202 // of the stack pointer is at this point. Any variable size objects 00203 // will be allocated after this, so we can still use the base pointer 00204 // to reference locals. 00205 if (RegInfo->hasBasePointer(MF)) 00206 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), BasePtr) 00207 .addReg(ARM::SP)); 00208 00209 // If the frame has variable sized objects then the epilogue must restore 00210 // the sp from fp. We can assume there's an FP here since hasFP already 00211 // checks for hasVarSizedObjects. 00212 if (MFI->hasVarSizedObjects()) 00213 AFI->setShouldRestoreSPFromFP(true); 00214 } 00215 00216 static bool isCalleeSavedRegister(unsigned Reg, const uint16_t *CSRegs) { 00217 for (unsigned i = 0; CSRegs[i]; ++i) 00218 if (Reg == CSRegs[i]) 00219 return true; 00220 return false; 00221 } 00222 00223 static bool isCSRestore(MachineInstr *MI, const uint16_t *CSRegs) { 00224 if (MI->getOpcode() == ARM::tLDRspi && 00225 MI->getOperand(1).isFI() && 00226 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)) 00227 return true; 00228 else if (MI->getOpcode() == ARM::tPOP) { 00229 // The first two operands are predicates. The last two are 00230 // imp-def and imp-use of SP. Check everything in between. 00231 for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i) 00232 if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs)) 00233 return false; 00234 return true; 00235 } 00236 return false; 00237 } 00238 00239 void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, 00240 MachineBasicBlock &MBB) const { 00241 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 00242 assert((MBBI->getOpcode() == ARM::tBX_RET || 00243 MBBI->getOpcode() == ARM::tPOP_RET) && 00244 "Can only insert epilog into returning blocks"); 00245 DebugLoc dl = MBBI->getDebugLoc(); 00246 MachineFrameInfo *MFI = MF.getFrameInfo(); 00247 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00248 const Thumb1RegisterInfo *RegInfo = 00249 static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 00250 const Thumb1InstrInfo &TII = 00251 *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 00252 00253 unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); 00254 unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); 00255 int NumBytes = (int)MFI->getStackSize(); 00256 const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(); 00257 unsigned FramePtr = RegInfo->getFrameRegister(MF); 00258 00259 if (!AFI->hasStackFrame()) { 00260 if (NumBytes != 0) 00261 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes); 00262 } else { 00263 // Unwind MBBI to point to first LDR / VLDRD. 00264 if (MBBI != MBB.begin()) { 00265 do 00266 --MBBI; 00267 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 00268 if (!isCSRestore(MBBI, CSRegs)) 00269 ++MBBI; 00270 } 00271 00272 // Move SP to start of FP callee save spill area. 00273 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 00274 AFI->getGPRCalleeSavedArea2Size() + 00275 AFI->getDPRCalleeSavedAreaSize()); 00276 00277 if (AFI->shouldRestoreSPFromFP()) { 00278 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 00279 // Reset SP based on frame pointer only if the stack frame extends beyond 00280 // frame pointer stack slot, the target is ELF and the function has FP, or 00281 // the target uses var sized objects. 00282 if (NumBytes) { 00283 assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) && 00284 "No scratch register to restore SP from FP!"); 00285 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, 00286 TII, *RegInfo); 00287 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), 00288 ARM::SP) 00289 .addReg(ARM::R4)); 00290 } else 00291 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), 00292 ARM::SP) 00293 .addReg(FramePtr)); 00294 } else { 00295 if (MBBI->getOpcode() == ARM::tBX_RET && 00296 &MBB.front() != MBBI && 00297 prior(MBBI)->getOpcode() == ARM::tPOP) { 00298 MachineBasicBlock::iterator PMBBI = prior(MBBI); 00299 emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes); 00300 } else 00301 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes); 00302 } 00303 } 00304 00305 if (ArgRegsSaveSize) { 00306 // Unlike T2 and ARM mode, the T1 pop instruction cannot restore 00307 // to LR, and we can't pop the value directly to the PC since 00308 // we need to update the SP after popping the value. Therefore, we 00309 // pop the old LR into R3 as a temporary. 00310 00311 // Move back past the callee-saved register restoration 00312 while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs)) 00313 ++MBBI; 00314 // Epilogue for vararg functions: pop LR to R3 and branch off it. 00315 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))) 00316 .addReg(ARM::R3, RegState::Define); 00317 00318 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize); 00319 00320 MachineInstrBuilder MIB = 00321 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)) 00322 .addReg(ARM::R3, RegState::Kill); 00323 AddDefaultPred(MIB); 00324 MIB.copyImplicitOps(&*MBBI); 00325 // erase the old tBX_RET instruction 00326 MBB.erase(MBBI); 00327 } 00328 } 00329 00330 bool Thumb1FrameLowering:: 00331 spillCalleeSavedRegisters(MachineBasicBlock &MBB, 00332 MachineBasicBlock::iterator MI, 00333 const std::vector<CalleeSavedInfo> &CSI, 00334 const TargetRegisterInfo *TRI) const { 00335 if (CSI.empty()) 00336 return false; 00337 00338 DebugLoc DL; 00339 MachineFunction &MF = *MBB.getParent(); 00340 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 00341 00342 if (MI != MBB.end()) DL = MI->getDebugLoc(); 00343 00344 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(ARM::tPUSH)); 00345 AddDefaultPred(MIB); 00346 for (unsigned i = CSI.size(); i != 0; --i) { 00347 unsigned Reg = CSI[i-1].getReg(); 00348 bool isKill = true; 00349 00350 // Add the callee-saved register as live-in unless it's LR and 00351 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress 00352 // then it's already added to the function and entry block live-in sets. 00353 if (Reg == ARM::LR) { 00354 MachineFunction &MF = *MBB.getParent(); 00355 if (MF.getFrameInfo()->isReturnAddressTaken() && 00356 MF.getRegInfo().isLiveIn(Reg)) 00357 isKill = false; 00358 } 00359 00360 if (isKill) 00361 MBB.addLiveIn(Reg); 00362 00363 MIB.addReg(Reg, getKillRegState(isKill)); 00364 } 00365 MIB.setMIFlags(MachineInstr::FrameSetup); 00366 return true; 00367 } 00368 00369 bool Thumb1FrameLowering:: 00370 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 00371 MachineBasicBlock::iterator MI, 00372 const std::vector<CalleeSavedInfo> &CSI, 00373 const TargetRegisterInfo *TRI) const { 00374 if (CSI.empty()) 00375 return false; 00376 00377 MachineFunction &MF = *MBB.getParent(); 00378 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00379 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 00380 00381 bool isVarArg = AFI->getArgRegsSaveSize() > 0; 00382 DebugLoc DL = MI->getDebugLoc(); 00383 MachineInstrBuilder MIB = BuildMI(MF, DL, TII.get(ARM::tPOP)); 00384 AddDefaultPred(MIB); 00385 00386 bool NumRegs = false; 00387 for (unsigned i = CSI.size(); i != 0; --i) { 00388 unsigned Reg = CSI[i-1].getReg(); 00389 if (Reg == ARM::LR) { 00390 // Special epilogue for vararg functions. See emitEpilogue 00391 if (isVarArg) 00392 continue; 00393 Reg = ARM::PC; 00394 (*MIB).setDesc(TII.get(ARM::tPOP_RET)); 00395 MIB.copyImplicitOps(&*MI); 00396 MI = MBB.erase(MI); 00397 } 00398 MIB.addReg(Reg, getDefRegState(true)); 00399 NumRegs = true; 00400 } 00401 00402 // It's illegal to emit pop instruction without operands. 00403 if (NumRegs) 00404 MBB.insert(MI, &*MIB); 00405 else 00406 MF.DeleteMachineInstr(MIB); 00407 00408 return true; 00409 }