MipsSEFrameLowering.cpp revision f9a5e7e4e9ca91111b15d97fe7461c9061931ff7
1//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===// 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// This file contains the Mips32/64 implementation of TargetFrameLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MipsSEFrameLowering.h" 15#include "MCTargetDesc/MipsBaseInfo.h" 16#include "MipsAnalyzeImmediate.h" 17#include "MipsMachineFunction.h" 18#include "MipsSEInstrInfo.h" 19#include "llvm/CodeGen/MachineFrameInfo.h" 20#include "llvm/CodeGen/MachineFunction.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/MachineModuleInfo.h" 23#include "llvm/CodeGen/MachineRegisterInfo.h" 24#include "llvm/CodeGen/RegisterScavenging.h" 25#include "llvm/IR/DataLayout.h" 26#include "llvm/IR/Function.h" 27#include "llvm/Support/CommandLine.h" 28#include "llvm/Target/TargetOptions.h" 29 30using namespace llvm; 31 32namespace { 33typedef MachineBasicBlock::iterator Iter; 34 35/// Helper class to expand pseudos. 36class ExpandPseudo { 37public: 38 ExpandPseudo(MachineFunction &MF); 39 bool expand(); 40 41private: 42 bool expandInstr(MachineBasicBlock &MBB, Iter I); 43 void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); 44 void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); 45 bool expandCopy(MachineBasicBlock &MBB, Iter I); 46 bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, 47 unsigned Src, unsigned RegSize); 48 49 MachineFunction &MF; 50 const MipsSEInstrInfo &TII; 51 const MipsRegisterInfo &RegInfo; 52 MachineRegisterInfo &MRI; 53}; 54} 55 56ExpandPseudo::ExpandPseudo(MachineFunction &MF_) 57 : MF(MF_), 58 TII(*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo())), 59 RegInfo(TII.getRegisterInfo()), MRI(MF.getRegInfo()) {} 60 61bool ExpandPseudo::expand() { 62 bool Expanded = false; 63 64 for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end(); 65 BB != BBEnd; ++BB) 66 for (Iter I = BB->begin(), End = BB->end(); I != End;) 67 Expanded |= expandInstr(*BB, I++); 68 69 return Expanded; 70} 71 72bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { 73 switch(I->getOpcode()) { 74 case Mips::LOAD_AC64: 75 case Mips::LOAD_AC64_P8: 76 case Mips::LOAD_AC_DSP: 77 case Mips::LOAD_AC_DSP_P8: 78 expandLoadACC(MBB, I, 4); 79 break; 80 case Mips::LOAD_AC128: 81 case Mips::LOAD_AC128_P8: 82 expandLoadACC(MBB, I, 8); 83 break; 84 case Mips::STORE_AC64: 85 case Mips::STORE_AC64_P8: 86 case Mips::STORE_AC_DSP: 87 case Mips::STORE_AC_DSP_P8: 88 expandStoreACC(MBB, I, 4); 89 break; 90 case Mips::STORE_AC128: 91 case Mips::STORE_AC128_P8: 92 expandStoreACC(MBB, I, 8); 93 break; 94 case TargetOpcode::COPY: 95 if (!expandCopy(MBB, I)) 96 return false; 97 break; 98 default: 99 return false; 100 } 101 102 MBB.erase(I); 103 return true; 104} 105 106void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, 107 unsigned RegSize) { 108 // load $vr0, FI 109 // copy lo, $vr0 110 // load $vr1, FI + 4 111 // copy hi, $vr1 112 113 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 114 115 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 116 unsigned VR0 = MRI.createVirtualRegister(RC); 117 unsigned VR1 = MRI.createVirtualRegister(RC); 118 unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 119 unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo); 120 unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi); 121 DebugLoc DL = I->getDebugLoc(); 122 const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); 123 124 TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0); 125 BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill); 126 TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize); 127 BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill); 128} 129 130void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I, 131 unsigned RegSize) { 132 // copy $vr0, lo 133 // store $vr0, FI 134 // copy $vr1, hi 135 // store $vr1, FI + 4 136 137 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 138 139 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 140 unsigned VR0 = MRI.createVirtualRegister(RC); 141 unsigned VR1 = MRI.createVirtualRegister(RC); 142 unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 143 unsigned SrcKill = getKillRegState(I->getOperand(0).isKill()); 144 unsigned Lo = RegInfo.getSubReg(Src, Mips::sub_lo); 145 unsigned Hi = RegInfo.getSubReg(Src, Mips::sub_hi); 146 DebugLoc DL = I->getDebugLoc(); 147 148 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(Lo, SrcKill); 149 TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0); 150 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(Hi, SrcKill); 151 TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize); 152} 153 154bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) { 155 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); 156 157 if (Mips::ACRegsDSPRegClass.contains(Dst, Src)) 158 return expandCopyACC(MBB, I, Dst, Src, 4); 159 160 if (Mips::ACRegs128RegClass.contains(Dst, Src)) 161 return expandCopyACC(MBB, I, Dst, Src, 8); 162 163 return false; 164} 165 166bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, 167 unsigned Src, unsigned RegSize) { 168 // copy $vr0, src_lo 169 // copy dst_lo, $vr0 170 // copy $vr1, src_hi 171 // copy dst_hi, $vr1 172 173 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 174 unsigned VR0 = MRI.createVirtualRegister(RC); 175 unsigned VR1 = MRI.createVirtualRegister(RC); 176 unsigned SrcKill = getKillRegState(I->getOperand(1).isKill()); 177 unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo); 178 unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi); 179 unsigned SrcLo = RegInfo.getSubReg(Src, Mips::sub_lo); 180 unsigned SrcHi = RegInfo.getSubReg(Src, Mips::sub_hi); 181 DebugLoc DL = I->getDebugLoc(); 182 183 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(SrcLo, SrcKill); 184 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo) 185 .addReg(VR0, RegState::Kill); 186 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill); 187 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi) 188 .addReg(VR1, RegState::Kill); 189 return true; 190} 191 192unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { 193 static const unsigned EhDataReg[] = { 194 Mips::A0, Mips::A1, Mips::A2, Mips::A3 195 }; 196 static const unsigned EhDataReg64[] = { 197 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 198 }; 199 200 return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; 201} 202 203void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { 204 MachineBasicBlock &MBB = MF.front(); 205 MachineFrameInfo *MFI = MF.getFrameInfo(); 206 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 207 const MipsRegisterInfo *RegInfo = 208 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 209 const MipsSEInstrInfo &TII = 210 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 211 MachineBasicBlock::iterator MBBI = MBB.begin(); 212 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 213 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 214 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 215 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 216 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 217 218 // First, compute final stack size. 219 uint64_t StackSize = MFI->getStackSize(); 220 221 // No need to allocate space on the stack. 222 if (StackSize == 0 && !MFI->adjustsStack()) return; 223 224 MachineModuleInfo &MMI = MF.getMMI(); 225 std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 226 MachineLocation DstML, SrcML; 227 228 // Adjust stack. 229 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 230 231 // emit ".cfi_def_cfa_offset StackSize" 232 MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 233 BuildMI(MBB, MBBI, dl, 234 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 235 DstML = MachineLocation(MachineLocation::VirtualFP); 236 SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 237 Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 238 239 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 240 241 if (CSI.size()) { 242 // Find the instruction past the last instruction that saves a callee-saved 243 // register to the stack. 244 for (unsigned i = 0; i < CSI.size(); ++i) 245 ++MBBI; 246 247 // Iterate over list of callee-saved registers and emit .cfi_offset 248 // directives. 249 MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 250 BuildMI(MBB, MBBI, dl, 251 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 252 253 for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 254 E = CSI.end(); I != E; ++I) { 255 int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 256 unsigned Reg = I->getReg(); 257 258 // If Reg is a double precision register, emit two cfa_offsets, 259 // one for each of the paired single precision registers. 260 if (Mips::AFGR64RegClass.contains(Reg)) { 261 MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 262 MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 263 MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); 264 MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); 265 266 if (!STI.isLittle()) 267 std::swap(SrcML0, SrcML1); 268 269 Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 270 Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 271 } else { 272 // Reg is either in CPURegs or FGR32. 273 DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 274 SrcML = MachineLocation(Reg); 275 Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 276 } 277 } 278 } 279 280 if (MipsFI->callsEhReturn()) { 281 const TargetRegisterClass *RC = STI.isABI_N64() ? 282 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 283 284 // Insert instructions that spill eh data registers. 285 for (int I = 0; I < 4; ++I) { 286 if (!MBB.isLiveIn(ehDataReg(I))) 287 MBB.addLiveIn(ehDataReg(I)); 288 TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, 289 MipsFI->getEhDataRegFI(I), RC, RegInfo); 290 } 291 292 // Emit .cfi_offset directives for eh data registers. 293 MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); 294 BuildMI(MBB, MBBI, dl, 295 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); 296 for (int I = 0; I < 4; ++I) { 297 int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); 298 DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 299 SrcML = MachineLocation(ehDataReg(I)); 300 Moves.push_back(MachineMove(CSLabel2, DstML, SrcML)); 301 } 302 } 303 304 // if framepointer enabled, set it to point to the stack pointer. 305 if (hasFP(MF)) { 306 // Insert instruction "move $fp, $sp" at this location. 307 BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 308 309 // emit ".cfi_def_cfa_register $fp" 310 MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 311 BuildMI(MBB, MBBI, dl, 312 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 313 DstML = MachineLocation(FP); 314 SrcML = MachineLocation(MachineLocation::VirtualFP); 315 Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 316 } 317} 318 319void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, 320 MachineBasicBlock &MBB) const { 321 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 322 MachineFrameInfo *MFI = MF.getFrameInfo(); 323 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 324 const MipsRegisterInfo *RegInfo = 325 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 326 const MipsSEInstrInfo &TII = 327 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 328 DebugLoc dl = MBBI->getDebugLoc(); 329 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 330 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 331 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 332 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 333 334 // if framepointer enabled, restore the stack pointer. 335 if (hasFP(MF)) { 336 // Find the first instruction that restores a callee-saved register. 337 MachineBasicBlock::iterator I = MBBI; 338 339 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 340 --I; 341 342 // Insert instruction "move $sp, $fp" at this location. 343 BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 344 } 345 346 if (MipsFI->callsEhReturn()) { 347 const TargetRegisterClass *RC = STI.isABI_N64() ? 348 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 349 350 // Find first instruction that restores a callee-saved register. 351 MachineBasicBlock::iterator I = MBBI; 352 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 353 --I; 354 355 // Insert instructions that restore eh data registers. 356 for (int J = 0; J < 4; ++J) { 357 TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), 358 RC, RegInfo); 359 } 360 } 361 362 // Get the number of bytes from FrameInfo 363 uint64_t StackSize = MFI->getStackSize(); 364 365 if (!StackSize) 366 return; 367 368 // Adjust stack. 369 TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 370} 371 372bool MipsSEFrameLowering:: 373spillCalleeSavedRegisters(MachineBasicBlock &MBB, 374 MachineBasicBlock::iterator MI, 375 const std::vector<CalleeSavedInfo> &CSI, 376 const TargetRegisterInfo *TRI) const { 377 MachineFunction *MF = MBB.getParent(); 378 MachineBasicBlock *EntryBlock = MF->begin(); 379 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 380 381 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 382 // Add the callee-saved register as live-in. Do not add if the register is 383 // RA and return address is taken, because it has already been added in 384 // method MipsTargetLowering::LowerRETURNADDR. 385 // It's killed at the spill, unless the register is RA and return address 386 // is taken. 387 unsigned Reg = CSI[i].getReg(); 388 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) 389 && MF->getFrameInfo()->isReturnAddressTaken(); 390 if (!IsRAAndRetAddrIsTaken) 391 EntryBlock->addLiveIn(Reg); 392 393 // Insert the spill to the stack frame. 394 bool IsKill = !IsRAAndRetAddrIsTaken; 395 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 396 TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, 397 CSI[i].getFrameIdx(), RC, TRI); 398 } 399 400 return true; 401} 402 403bool 404MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 405 const MachineFrameInfo *MFI = MF.getFrameInfo(); 406 407 // Reserve call frame if the size of the maximum call frame fits into 16-bit 408 // immediate field and there are no variable sized objects on the stack. 409 // Make sure the second register scavenger spill slot can be accessed with one 410 // instruction. 411 return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) && 412 !MFI->hasVarSizedObjects(); 413} 414 415// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 416void MipsSEFrameLowering:: 417eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 418 MachineBasicBlock::iterator I) const { 419 const MipsSEInstrInfo &TII = 420 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 421 422 if (!hasReservedCallFrame(MF)) { 423 int64_t Amount = I->getOperand(0).getImm(); 424 425 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 426 Amount = -Amount; 427 428 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 429 TII.adjustStackPtr(SP, Amount, MBB, I); 430 } 431 432 MBB.erase(I); 433} 434 435void MipsSEFrameLowering:: 436processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 437 RegScavenger *RS) const { 438 MachineRegisterInfo &MRI = MF.getRegInfo(); 439 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 440 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 441 442 // Mark $fp as used if function has dedicated frame pointer. 443 if (hasFP(MF)) 444 MRI.setPhysRegUsed(FP); 445 446 // Create spill slots for eh data registers if function calls eh_return. 447 if (MipsFI->callsEhReturn()) 448 MipsFI->createEhDataRegsFI(); 449 450 // Expand pseudo instructions which load, store or copy accumulators. 451 // Add an emergency spill slot if a pseudo was expanded. 452 if (ExpandPseudo(MF).expand()) { 453 // The spill slot should be half the size of the accumulator. If target is 454 // mips64, it should be 64-bit, otherwise it should be 32-bt. 455 const TargetRegisterClass *RC = STI.hasMips64() ? 456 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 457 int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 458 RC->getAlignment(), false); 459 RS->addScavengingFrameIndex(FI); 460 } 461 462 // Set scavenging frame index if necessary. 463 uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() + 464 estimateStackSize(MF); 465 466 if (isInt<16>(MaxSPOffset)) 467 return; 468 469 const TargetRegisterClass *RC = STI.isABI_N64() ? 470 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 471 int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 472 RC->getAlignment(), false); 473 RS->addScavengingFrameIndex(FI); 474} 475 476const MipsFrameLowering * 477llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { 478 return new MipsSEFrameLowering(ST); 479} 480