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