1 //===-- LoongArchFrameLowering.cpp - LoongArch Frame Information -*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the LoongArch implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LoongArchFrameLowering.h" 14 #include "LoongArchMachineFunctionInfo.h" 15 #include "LoongArchSubtarget.h" 16 #include "MCTargetDesc/LoongArchBaseInfo.h" 17 #include "MCTargetDesc/LoongArchMCTargetDesc.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/RegisterScavenging.h" 23 #include "llvm/IR/DiagnosticInfo.h" 24 #include "llvm/MC/MCDwarf.h" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "loongarch-frame-lowering" 29 30 // Return true if the specified function should have a dedicated frame 31 // pointer register. This is true if frame pointer elimination is 32 // disabled, if it needs dynamic stack realignment, if the function has 33 // variable sized allocas, or if the frame address is taken. 34 bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const { 35 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 36 37 const MachineFrameInfo &MFI = MF.getFrameInfo(); 38 return MF.getTarget().Options.DisableFramePointerElim(MF) || 39 RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || 40 MFI.isFrameAddressTaken(); 41 } 42 43 bool LoongArchFrameLowering::hasBP(const MachineFunction &MF) const { 44 const MachineFrameInfo &MFI = MF.getFrameInfo(); 45 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 46 47 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF); 48 } 49 50 void LoongArchFrameLowering::adjustReg(MachineBasicBlock &MBB, 51 MachineBasicBlock::iterator MBBI, 52 const DebugLoc &DL, Register DestReg, 53 Register SrcReg, int64_t Val, 54 MachineInstr::MIFlag Flag) const { 55 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 56 bool IsLA64 = STI.is64Bit(); 57 unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; 58 59 if (DestReg == SrcReg && Val == 0) 60 return; 61 62 if (isInt<12>(Val)) { 63 // addi.w/d $DstReg, $SrcReg, Val 64 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 65 .addReg(SrcReg) 66 .addImm(Val) 67 .setMIFlag(Flag); 68 return; 69 } 70 71 // Try to split the offset across two ADDIs. We need to keep the stack pointer 72 // aligned after each ADDI. We need to determine the maximum value we can put 73 // in each ADDI. In the negative direction, we can use -2048 which is always 74 // sufficiently aligned. In the positive direction, we need to find the 75 // largest 12-bit immediate that is aligned. Exclude -4096 since it can be 76 // created with LU12I.W. 77 assert(getStackAlign().value() < 2048 && "Stack alignment too large"); 78 int64_t MaxPosAdjStep = 2048 - getStackAlign().value(); 79 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) { 80 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep; 81 Val -= FirstAdj; 82 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 83 .addReg(SrcReg) 84 .addImm(FirstAdj) 85 .setMIFlag(Flag); 86 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 87 .addReg(DestReg, RegState::Kill) 88 .addImm(Val) 89 .setMIFlag(Flag); 90 return; 91 } 92 93 unsigned Opc = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W; 94 if (Val < 0) { 95 Val = -Val; 96 Opc = IsLA64 ? LoongArch::SUB_D : LoongArch::SUB_W; 97 } 98 99 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 100 Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); 101 TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag); 102 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 103 .addReg(SrcReg) 104 .addReg(ScratchReg, RegState::Kill) 105 .setMIFlag(Flag); 106 } 107 108 // Determine the size of the frame and maximum call frame size. 109 void LoongArchFrameLowering::determineFrameLayout(MachineFunction &MF) const { 110 MachineFrameInfo &MFI = MF.getFrameInfo(); 111 112 // Get the number of bytes to allocate from the FrameInfo. 113 uint64_t FrameSize = MFI.getStackSize(); 114 115 // Make sure the frame is aligned. 116 FrameSize = alignTo(FrameSize, getStackAlign()); 117 118 // Update frame info. 119 MFI.setStackSize(FrameSize); 120 } 121 122 static uint64_t estimateFunctionSizeInBytes(const LoongArchInstrInfo *TII, 123 const MachineFunction &MF) { 124 uint64_t FuncSize = 0; 125 for (auto &MBB : MF) 126 for (auto &MI : MBB) 127 FuncSize += TII->getInstSizeInBytes(MI); 128 return FuncSize; 129 } 130 131 static bool needScavSlotForCFR(MachineFunction &MF) { 132 if (!MF.getSubtarget<LoongArchSubtarget>().hasBasicF()) 133 return false; 134 for (auto &MBB : MF) 135 for (auto &MI : MBB) 136 if (MI.getOpcode() == LoongArch::PseudoST_CFR) 137 return true; 138 return false; 139 } 140 141 void LoongArchFrameLowering::processFunctionBeforeFrameFinalized( 142 MachineFunction &MF, RegScavenger *RS) const { 143 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 144 const TargetRegisterClass &RC = LoongArch::GPRRegClass; 145 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 146 LoongArchMachineFunctionInfo *LAFI = 147 MF.getInfo<LoongArchMachineFunctionInfo>(); 148 MachineFrameInfo &MFI = MF.getFrameInfo(); 149 150 unsigned ScavSlotsNum = 0; 151 152 // Far branches beyond 27-bit offset require a spill slot for scratch register. 153 bool IsLargeFunction = !isInt<27>(estimateFunctionSizeInBytes(TII, MF)); 154 if (IsLargeFunction) 155 ScavSlotsNum = 1; 156 157 // estimateStackSize has been observed to under-estimate the final stack 158 // size, so give ourselves wiggle-room by checking for stack size 159 // representable an 11-bit signed field rather than 12-bits. 160 if (!isInt<11>(MFI.estimateStackSize(MF))) 161 ScavSlotsNum = std::max(ScavSlotsNum, 1u); 162 163 // For CFR spill. 164 if (needScavSlotForCFR(MF)) 165 ++ScavSlotsNum; 166 167 // Create emergency spill slots. 168 for (unsigned i = 0; i < ScavSlotsNum; ++i) { 169 int FI = MFI.CreateStackObject(RI->getSpillSize(RC), RI->getSpillAlign(RC), 170 false); 171 RS->addScavengingFrameIndex(FI); 172 if (IsLargeFunction && LAFI->getBranchRelaxationSpillFrameIndex() == -1) 173 LAFI->setBranchRelaxationSpillFrameIndex(FI); 174 LLVM_DEBUG(dbgs() << "Allocated FI(" << FI 175 << ") as the emergency spill slot.\n"); 176 } 177 } 178 179 void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, 180 MachineBasicBlock &MBB) const { 181 MachineFrameInfo &MFI = MF.getFrameInfo(); 182 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 183 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 184 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 185 MachineBasicBlock::iterator MBBI = MBB.begin(); 186 bool IsLA64 = STI.is64Bit(); 187 188 Register SPReg = LoongArch::R3; 189 Register FPReg = LoongArch::R22; 190 191 // Debug location must be unknown since the first debug location is used 192 // to determine the end of the prologue. 193 DebugLoc DL; 194 // All calls are tail calls in GHC calling conv, and functions have no 195 // prologue/epilogue. 196 if (MF.getFunction().getCallingConv() == CallingConv::GHC) 197 return; 198 // Determine the correct frame layout 199 determineFrameLayout(MF); 200 201 // First, compute final stack size. 202 uint64_t StackSize = MFI.getStackSize(); 203 uint64_t RealStackSize = StackSize; 204 205 // Early exit if there is no need to allocate space in the stack. 206 if (StackSize == 0 && !MFI.adjustsStack()) 207 return; 208 209 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF, true); 210 uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount; 211 // Split the SP adjustment to reduce the offsets of callee saved spill. 212 if (FirstSPAdjustAmount) 213 StackSize = FirstSPAdjustAmount; 214 215 // Adjust stack. 216 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); 217 if (FirstSPAdjustAmount != 2048 || SecondSPAdjustAmount == 0) { 218 // Emit ".cfi_def_cfa_offset StackSize". 219 unsigned CFIIndex = 220 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize)); 221 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 222 .addCFIIndex(CFIIndex) 223 .setMIFlag(MachineInstr::FrameSetup); 224 } 225 226 const auto &CSI = MFI.getCalleeSavedInfo(); 227 228 // The frame pointer is callee-saved, and code has been generated for us to 229 // save it to the stack. We need to skip over the storing of callee-saved 230 // registers as the frame pointer must be modified after it has been saved 231 // to the stack, not before. 232 std::advance(MBBI, CSI.size()); 233 234 // Iterate over list of callee-saved registers and emit .cfi_offset 235 // directives. 236 for (const auto &Entry : CSI) { 237 int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx()); 238 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 239 nullptr, RI->getDwarfRegNum(Entry.getReg(), true), Offset)); 240 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 241 .addCFIIndex(CFIIndex) 242 .setMIFlag(MachineInstr::FrameSetup); 243 } 244 245 // Generate new FP. 246 if (hasFP(MF)) { 247 adjustReg(MBB, MBBI, DL, FPReg, SPReg, 248 StackSize - LoongArchFI->getVarArgsSaveSize(), 249 MachineInstr::FrameSetup); 250 251 // Emit ".cfi_def_cfa $fp, LoongArchFI->getVarArgsSaveSize()" 252 unsigned CFIIndex = MF.addFrameInst( 253 MCCFIInstruction::cfiDefCfa(nullptr, RI->getDwarfRegNum(FPReg, true), 254 LoongArchFI->getVarArgsSaveSize())); 255 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 256 .addCFIIndex(CFIIndex) 257 .setMIFlag(MachineInstr::FrameSetup); 258 } 259 260 // Emit the second SP adjustment after saving callee saved registers. 261 if (FirstSPAdjustAmount && SecondSPAdjustAmount) { 262 if (hasFP(MF)) { 263 assert(SecondSPAdjustAmount > 0 && 264 "SecondSPAdjustAmount should be greater than zero"); 265 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount, 266 MachineInstr::FrameSetup); 267 } else { 268 // FIXME: RegScavenger will place the spill instruction before the 269 // prologue if a VReg is created in the prologue. This will pollute the 270 // caller's stack data. Therefore, until there is better way, we just use 271 // the `addi.w/d` instruction for stack adjustment to ensure that VReg 272 // will not be created. 273 for (int Val = SecondSPAdjustAmount; Val > 0; Val -= 2048) 274 BuildMI(MBB, MBBI, DL, 275 TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), SPReg) 276 .addReg(SPReg) 277 .addImm(Val < 2048 ? -Val : -2048) 278 .setMIFlag(MachineInstr::FrameSetup); 279 280 // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0", 281 // don't emit an sp-based .cfi_def_cfa_offset 282 // Emit ".cfi_def_cfa_offset RealStackSize" 283 unsigned CFIIndex = MF.addFrameInst( 284 MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize)); 285 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 286 .addCFIIndex(CFIIndex) 287 .setMIFlag(MachineInstr::FrameSetup); 288 } 289 } 290 291 if (hasFP(MF)) { 292 // Realign stack. 293 if (RI->hasStackRealignment(MF)) { 294 unsigned Align = Log2(MFI.getMaxAlign()); 295 assert(Align > 0 && "The stack realignment size is invalid!"); 296 BuildMI(MBB, MBBI, DL, 297 TII->get(IsLA64 ? LoongArch::BSTRINS_D : LoongArch::BSTRINS_W), 298 SPReg) 299 .addReg(SPReg) 300 .addReg(LoongArch::R0) 301 .addImm(Align - 1) 302 .addImm(0) 303 .setMIFlag(MachineInstr::FrameSetup); 304 // FP will be used to restore the frame in the epilogue, so we need 305 // another base register BP to record SP after re-alignment. SP will 306 // track the current stack after allocating variable sized objects. 307 if (hasBP(MF)) { 308 // move BP, $sp 309 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::OR), 310 LoongArchABI::getBPReg()) 311 .addReg(SPReg) 312 .addReg(LoongArch::R0) 313 .setMIFlag(MachineInstr::FrameSetup); 314 } 315 } 316 } 317 } 318 319 void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF, 320 MachineBasicBlock &MBB) const { 321 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 322 MachineFrameInfo &MFI = MF.getFrameInfo(); 323 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 324 Register SPReg = LoongArch::R3; 325 // All calls are tail calls in GHC calling conv, and functions have no 326 // prologue/epilogue. 327 if (MF.getFunction().getCallingConv() == CallingConv::GHC) 328 return; 329 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); 330 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 331 332 const auto &CSI = MFI.getCalleeSavedInfo(); 333 // Skip to before the restores of callee-saved registers. 334 auto LastFrameDestroy = MBBI; 335 if (!CSI.empty()) 336 LastFrameDestroy = std::prev(MBBI, CSI.size()); 337 338 // Get the number of bytes from FrameInfo. 339 uint64_t StackSize = MFI.getStackSize(); 340 341 // Restore the stack pointer. 342 if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects()) { 343 assert(hasFP(MF) && "frame pointer should not have been eliminated"); 344 adjustReg(MBB, LastFrameDestroy, DL, SPReg, LoongArch::R22, 345 -StackSize + LoongArchFI->getVarArgsSaveSize(), 346 MachineInstr::FrameDestroy); 347 } 348 349 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); 350 if (FirstSPAdjustAmount) { 351 uint64_t SecondSPAdjustAmount = StackSize - FirstSPAdjustAmount; 352 assert(SecondSPAdjustAmount > 0 && 353 "SecondSPAdjustAmount should be greater than zero"); 354 355 adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount, 356 MachineInstr::FrameDestroy); 357 StackSize = FirstSPAdjustAmount; 358 } 359 360 // Deallocate stack 361 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); 362 } 363 364 // We would like to split the SP adjustment to reduce prologue/epilogue 365 // as following instructions. In this way, the offset of the callee saved 366 // register could fit in a single store. 367 // e.g. 368 // addi.d $sp, $sp, -2032 369 // st.d $ra, $sp, 2024 370 // st.d $fp, $sp, 2016 371 // addi.d $sp, $sp, -16 372 uint64_t 373 LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF, 374 bool IsPrologue) const { 375 const MachineFrameInfo &MFI = MF.getFrameInfo(); 376 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 377 378 // Return the FirstSPAdjustAmount if the StackSize can not fit in a signed 379 // 12-bit and there exists a callee-saved register needing to be pushed. 380 if (!isInt<12>(MFI.getStackSize())) { 381 // FirstSPAdjustAmount is chosen as (2048 - StackAlign) because 2048 will 382 // cause sp = sp + 2048 in the epilogue to be split into multiple 383 // instructions. Offsets smaller than 2048 can fit in a single load/store 384 // instruction, and we have to stick with the stack alignment. 385 // So (2048 - StackAlign) will satisfy the stack alignment. 386 // 387 // FIXME: This place may seem odd. When using multiple ADDI instructions to 388 // adjust the stack in Prologue, and there are no callee-saved registers, we 389 // can take advantage of the logic of split sp ajustment to reduce code 390 // changes. 391 return CSI.size() > 0 ? 2048 - getStackAlign().value() 392 : (IsPrologue ? 2048 : 0); 393 } 394 return 0; 395 } 396 397 void LoongArchFrameLowering::determineCalleeSaves(MachineFunction &MF, 398 BitVector &SavedRegs, 399 RegScavenger *RS) const { 400 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 401 // Unconditionally spill RA and FP only if the function uses a frame 402 // pointer. 403 if (hasFP(MF)) { 404 SavedRegs.set(LoongArch::R1); 405 SavedRegs.set(LoongArch::R22); 406 } 407 // Mark BP as used if function has dedicated base pointer. 408 if (hasBP(MF)) 409 SavedRegs.set(LoongArchABI::getBPReg()); 410 } 411 412 // Do not preserve stack space within prologue for outgoing variables if the 413 // function contains variable size objects. 414 // Let eliminateCallFramePseudoInstr preserve stack space for it. 415 bool LoongArchFrameLowering::hasReservedCallFrame( 416 const MachineFunction &MF) const { 417 return !MF.getFrameInfo().hasVarSizedObjects(); 418 } 419 420 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. 421 MachineBasicBlock::iterator 422 LoongArchFrameLowering::eliminateCallFramePseudoInstr( 423 MachineFunction &MF, MachineBasicBlock &MBB, 424 MachineBasicBlock::iterator MI) const { 425 Register SPReg = LoongArch::R3; 426 DebugLoc DL = MI->getDebugLoc(); 427 428 if (!hasReservedCallFrame(MF)) { 429 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and 430 // ADJCALLSTACKUP must be converted to instructions manipulating the stack 431 // pointer. This is necessary when there is a variable length stack 432 // allocation (e.g. alloca), which means it's not possible to allocate 433 // space for outgoing arguments from within the function prologue. 434 int64_t Amount = MI->getOperand(0).getImm(); 435 436 if (Amount != 0) { 437 // Ensure the stack remains aligned after adjustment. 438 Amount = alignSPAdjust(Amount); 439 440 if (MI->getOpcode() == LoongArch::ADJCALLSTACKDOWN) 441 Amount = -Amount; 442 443 adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); 444 } 445 } 446 447 return MBB.erase(MI); 448 } 449 450 bool LoongArchFrameLowering::spillCalleeSavedRegisters( 451 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 452 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 453 if (CSI.empty()) 454 return true; 455 456 MachineFunction *MF = MBB.getParent(); 457 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 458 459 // Insert the spill to the stack frame. 460 for (auto &CS : CSI) { 461 Register Reg = CS.getReg(); 462 // If the register is RA and the return address is taken by method 463 // LoongArchTargetLowering::lowerRETURNADDR, don't set kill flag. 464 bool IsKill = 465 !(Reg == LoongArch::R1 && MF->getFrameInfo().isReturnAddressTaken()); 466 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 467 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, CS.getFrameIdx(), RC, TRI, 468 Register()); 469 } 470 471 return true; 472 } 473 474 StackOffset LoongArchFrameLowering::getFrameIndexReference( 475 const MachineFunction &MF, int FI, Register &FrameReg) const { 476 const MachineFrameInfo &MFI = MF.getFrameInfo(); 477 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 478 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 479 uint64_t StackSize = MFI.getStackSize(); 480 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); 481 482 // Callee-saved registers should be referenced relative to the stack 483 // pointer (positive offset), otherwise use the frame pointer (negative 484 // offset). 485 const auto &CSI = MFI.getCalleeSavedInfo(); 486 int MinCSFI = 0; 487 int MaxCSFI = -1; 488 StackOffset Offset = 489 StackOffset::getFixed(MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + 490 MFI.getOffsetAdjustment()); 491 492 if (CSI.size()) { 493 MinCSFI = CSI[0].getFrameIdx(); 494 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 495 } 496 497 if (FI >= MinCSFI && FI <= MaxCSFI) { 498 FrameReg = LoongArch::R3; 499 if (FirstSPAdjustAmount) 500 Offset += StackOffset::getFixed(FirstSPAdjustAmount); 501 else 502 Offset += StackOffset::getFixed(StackSize); 503 } else if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { 504 // If the stack was realigned, the frame pointer is set in order to allow 505 // SP to be restored, so we need another base register to record the stack 506 // after realignment. 507 FrameReg = hasBP(MF) ? LoongArchABI::getBPReg() : LoongArch::R3; 508 Offset += StackOffset::getFixed(StackSize); 509 } else { 510 FrameReg = RI->getFrameRegister(MF); 511 if (hasFP(MF)) 512 Offset += StackOffset::getFixed(LoongArchFI->getVarArgsSaveSize()); 513 else 514 Offset += StackOffset::getFixed(StackSize); 515 } 516 517 return Offset; 518 } 519 520 bool LoongArchFrameLowering::enableShrinkWrapping( 521 const MachineFunction &MF) const { 522 // Keep the conventional code flow when not optimizing. 523 if (MF.getFunction().hasOptNone()) 524 return false; 525 526 return true; 527 } 528