1 //===-- RISCVFrameLowering.cpp - RISCV Frame Information ------------------===// 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 RISCV implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "RISCVFrameLowering.h" 14 #include "RISCVMachineFunctionInfo.h" 15 #include "RISCVSubtarget.h" 16 #include "llvm/CodeGen/MachineFrameInfo.h" 17 #include "llvm/CodeGen/MachineFunction.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/CodeGen/RegisterScavenging.h" 21 #include "llvm/MC/MCDwarf.h" 22 23 using namespace llvm; 24 25 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { 26 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 27 28 const MachineFrameInfo &MFI = MF.getFrameInfo(); 29 return MF.getTarget().Options.DisableFramePointerElim(MF) || 30 RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() || 31 MFI.isFrameAddressTaken(); 32 } 33 34 // Determines the size of the frame and maximum call frame size. 35 void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const { 36 MachineFrameInfo &MFI = MF.getFrameInfo(); 37 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 38 39 // Get the number of bytes to allocate from the FrameInfo. 40 uint64_t FrameSize = MFI.getStackSize(); 41 42 // Get the alignment. 43 unsigned StackAlign = getStackAlignment(); 44 if (RI->needsStackRealignment(MF)) { 45 unsigned MaxStackAlign = std::max(StackAlign, MFI.getMaxAlignment()); 46 FrameSize += (MaxStackAlign - StackAlign); 47 StackAlign = MaxStackAlign; 48 } 49 50 // Set Max Call Frame Size 51 uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign); 52 MFI.setMaxCallFrameSize(MaxCallSize); 53 54 // Make sure the frame is aligned. 55 FrameSize = alignTo(FrameSize, StackAlign); 56 57 // Update frame info. 58 MFI.setStackSize(FrameSize); 59 } 60 61 void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB, 62 MachineBasicBlock::iterator MBBI, 63 const DebugLoc &DL, Register DestReg, 64 Register SrcReg, int64_t Val, 65 MachineInstr::MIFlag Flag) const { 66 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 67 const RISCVInstrInfo *TII = STI.getInstrInfo(); 68 69 if (DestReg == SrcReg && Val == 0) 70 return; 71 72 if (isInt<12>(Val)) { 73 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg) 74 .addReg(SrcReg) 75 .addImm(Val) 76 .setMIFlag(Flag); 77 } else { 78 unsigned Opc = RISCV::ADD; 79 bool isSub = Val < 0; 80 if (isSub) { 81 Val = -Val; 82 Opc = RISCV::SUB; 83 } 84 85 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); 86 TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag); 87 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 88 .addReg(SrcReg) 89 .addReg(ScratchReg, RegState::Kill) 90 .setMIFlag(Flag); 91 } 92 } 93 94 // Returns the register used to hold the frame pointer. 95 static Register getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; } 96 97 // Returns the register used to hold the stack pointer. 98 static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; } 99 100 void RISCVFrameLowering::emitPrologue(MachineFunction &MF, 101 MachineBasicBlock &MBB) const { 102 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 103 104 MachineFrameInfo &MFI = MF.getFrameInfo(); 105 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 106 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 107 const RISCVInstrInfo *TII = STI.getInstrInfo(); 108 MachineBasicBlock::iterator MBBI = MBB.begin(); 109 110 if (RI->needsStackRealignment(MF) && MFI.hasVarSizedObjects()) { 111 report_fatal_error( 112 "RISC-V backend can't currently handle functions that need stack " 113 "realignment and have variable sized objects"); 114 } 115 116 Register FPReg = getFPReg(STI); 117 Register SPReg = getSPReg(STI); 118 119 // Debug location must be unknown since the first debug location is used 120 // to determine the end of the prologue. 121 DebugLoc DL; 122 123 // Determine the correct frame layout 124 determineFrameLayout(MF); 125 126 // FIXME (note copied from Lanai): This appears to be overallocating. Needs 127 // investigation. Get the number of bytes to allocate from the FrameInfo. 128 uint64_t StackSize = MFI.getStackSize(); 129 130 // Early exit if there is no need to allocate on the stack 131 if (StackSize == 0 && !MFI.adjustsStack()) 132 return; 133 134 // Allocate space on the stack if necessary. 135 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); 136 137 // Emit ".cfi_def_cfa_offset StackSize" 138 unsigned CFIIndex = MF.addFrameInst( 139 MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize)); 140 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 141 .addCFIIndex(CFIIndex); 142 143 // The frame pointer is callee-saved, and code has been generated for us to 144 // save it to the stack. We need to skip over the storing of callee-saved 145 // registers as the frame pointer must be modified after it has been saved 146 // to the stack, not before. 147 // FIXME: assumes exactly one instruction is used to save each callee-saved 148 // register. 149 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 150 std::advance(MBBI, CSI.size()); 151 152 // Iterate over list of callee-saved registers and emit .cfi_offset 153 // directives. 154 for (const auto &Entry : CSI) { 155 int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx()); 156 Register Reg = Entry.getReg(); 157 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 158 nullptr, RI->getDwarfRegNum(Reg, true), Offset)); 159 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 160 .addCFIIndex(CFIIndex); 161 } 162 163 // Generate new FP. 164 if (hasFP(MF)) { 165 adjustReg(MBB, MBBI, DL, FPReg, SPReg, 166 StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); 167 168 // Emit ".cfi_def_cfa $fp, 0" 169 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( 170 nullptr, RI->getDwarfRegNum(FPReg, true), 0)); 171 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 172 .addCFIIndex(CFIIndex); 173 174 // Realign Stack 175 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 176 if (RI->needsStackRealignment(MF)) { 177 unsigned MaxAlignment = MFI.getMaxAlignment(); 178 179 const RISCVInstrInfo *TII = STI.getInstrInfo(); 180 if (isInt<12>(-(int)MaxAlignment)) { 181 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg) 182 .addReg(SPReg) 183 .addImm(-(int)MaxAlignment); 184 } else { 185 unsigned ShiftAmount = countTrailingZeros(MaxAlignment); 186 Register VR = 187 MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 188 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR) 189 .addReg(SPReg) 190 .addImm(ShiftAmount); 191 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg) 192 .addReg(VR) 193 .addImm(ShiftAmount); 194 } 195 } 196 } 197 } 198 199 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, 200 MachineBasicBlock &MBB) const { 201 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 202 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 203 MachineFrameInfo &MFI = MF.getFrameInfo(); 204 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 205 DebugLoc DL = MBBI->getDebugLoc(); 206 const RISCVInstrInfo *TII = STI.getInstrInfo(); 207 Register FPReg = getFPReg(STI); 208 Register SPReg = getSPReg(STI); 209 210 // Skip to before the restores of callee-saved registers 211 // FIXME: assumes exactly one instruction is used to restore each 212 // callee-saved register. 213 auto LastFrameDestroy = std::prev(MBBI, MFI.getCalleeSavedInfo().size()); 214 215 uint64_t StackSize = MFI.getStackSize(); 216 uint64_t FPOffset = StackSize - RVFI->getVarArgsSaveSize(); 217 218 // Restore the stack pointer using the value of the frame pointer. Only 219 // necessary if the stack pointer was modified, meaning the stack size is 220 // unknown. 221 if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) { 222 assert(hasFP(MF) && "frame pointer should not have been eliminated"); 223 adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -FPOffset, 224 MachineInstr::FrameDestroy); 225 } 226 227 if (hasFP(MF)) { 228 // To find the instruction restoring FP from stack. 229 for (auto &I = LastFrameDestroy; I != MBBI; ++I) { 230 if (I->mayLoad() && I->getOperand(0).isReg()) { 231 Register DestReg = I->getOperand(0).getReg(); 232 if (DestReg == FPReg) { 233 // If there is frame pointer, after restoring $fp registers, we 234 // need adjust CFA to ($sp - FPOffset). 235 // Emit ".cfi_def_cfa $sp, -FPOffset" 236 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( 237 nullptr, RI->getDwarfRegNum(SPReg, true), -FPOffset)); 238 BuildMI(MBB, std::next(I), DL, 239 TII->get(TargetOpcode::CFI_INSTRUCTION)) 240 .addCFIIndex(CFIIndex); 241 break; 242 } 243 } 244 } 245 } 246 247 // Add CFI directives for callee-saved registers. 248 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 249 // Iterate over list of callee-saved registers and emit .cfi_restore 250 // directives. 251 for (const auto &Entry : CSI) { 252 Register Reg = Entry.getReg(); 253 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore( 254 nullptr, RI->getDwarfRegNum(Reg, true))); 255 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 256 .addCFIIndex(CFIIndex); 257 } 258 259 // Deallocate stack 260 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); 261 262 // After restoring $sp, we need to adjust CFA to $(sp + 0) 263 // Emit ".cfi_def_cfa_offset 0" 264 unsigned CFIIndex = 265 MF.addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, 0)); 266 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 267 .addCFIIndex(CFIIndex); 268 } 269 270 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, 271 int FI, 272 unsigned &FrameReg) const { 273 const MachineFrameInfo &MFI = MF.getFrameInfo(); 274 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 275 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 276 277 // Callee-saved registers should be referenced relative to the stack 278 // pointer (positive offset), otherwise use the frame pointer (negative 279 // offset). 280 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 281 int MinCSFI = 0; 282 int MaxCSFI = -1; 283 284 int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + 285 MFI.getOffsetAdjustment(); 286 287 if (CSI.size()) { 288 MinCSFI = CSI[0].getFrameIdx(); 289 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 290 } 291 292 if (FI >= MinCSFI && FI <= MaxCSFI) { 293 FrameReg = RISCV::X2; 294 Offset += MF.getFrameInfo().getStackSize(); 295 } else if (RI->needsStackRealignment(MF)) { 296 assert(!MFI.hasVarSizedObjects() && 297 "Unexpected combination of stack realignment and varsized objects"); 298 // If the stack was realigned, the frame pointer is set in order to allow 299 // SP to be restored, but we still access stack objects using SP. 300 FrameReg = RISCV::X2; 301 Offset += MF.getFrameInfo().getStackSize(); 302 } else { 303 FrameReg = RI->getFrameRegister(MF); 304 if (hasFP(MF)) 305 Offset += RVFI->getVarArgsSaveSize(); 306 else 307 Offset += MF.getFrameInfo().getStackSize(); 308 } 309 return Offset; 310 } 311 312 void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, 313 BitVector &SavedRegs, 314 RegScavenger *RS) const { 315 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 316 // Unconditionally spill RA and FP only if the function uses a frame 317 // pointer. 318 if (hasFP(MF)) { 319 SavedRegs.set(RISCV::X1); 320 SavedRegs.set(RISCV::X8); 321 } 322 323 // If interrupt is enabled and there are calls in the handler, 324 // unconditionally save all Caller-saved registers and 325 // all FP registers, regardless whether they are used. 326 MachineFrameInfo &MFI = MF.getFrameInfo(); 327 328 if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) { 329 330 static const MCPhysReg CSRegs[] = { RISCV::X1, /* ra */ 331 RISCV::X5, RISCV::X6, RISCV::X7, /* t0-t2 */ 332 RISCV::X10, RISCV::X11, /* a0-a1, a2-a7 */ 333 RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17, 334 RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31, 0 /* t3-t6 */ 335 }; 336 337 for (unsigned i = 0; CSRegs[i]; ++i) 338 SavedRegs.set(CSRegs[i]); 339 340 if (MF.getSubtarget<RISCVSubtarget>().hasStdExtD() || 341 MF.getSubtarget<RISCVSubtarget>().hasStdExtF()) { 342 343 // If interrupt is enabled, this list contains all FP registers. 344 const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs(); 345 346 for (unsigned i = 0; Regs[i]; ++i) 347 if (RISCV::FPR32RegClass.contains(Regs[i]) || 348 RISCV::FPR64RegClass.contains(Regs[i])) 349 SavedRegs.set(Regs[i]); 350 } 351 } 352 } 353 354 void RISCVFrameLowering::processFunctionBeforeFrameFinalized( 355 MachineFunction &MF, RegScavenger *RS) const { 356 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 357 MachineFrameInfo &MFI = MF.getFrameInfo(); 358 const TargetRegisterClass *RC = &RISCV::GPRRegClass; 359 // estimateStackSize has been observed to under-estimate the final stack 360 // size, so give ourselves wiggle-room by checking for stack size 361 // representable an 11-bit signed field rather than 12-bits. 362 // FIXME: It may be possible to craft a function with a small stack that 363 // still needs an emergency spill slot for branch relaxation. This case 364 // would currently be missed. 365 if (!isInt<11>(MFI.estimateStackSize(MF))) { 366 int RegScavFI = MFI.CreateStackObject( 367 RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false); 368 RS->addScavengingFrameIndex(RegScavFI); 369 } 370 } 371 372 // Not preserve stack space within prologue for outgoing variables when the 373 // function contains variable size objects and let eliminateCallFramePseudoInstr 374 // preserve stack space for it. 375 bool RISCVFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 376 return !MF.getFrameInfo().hasVarSizedObjects(); 377 } 378 379 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. 380 MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr( 381 MachineFunction &MF, MachineBasicBlock &MBB, 382 MachineBasicBlock::iterator MI) const { 383 Register SPReg = RISCV::X2; 384 DebugLoc DL = MI->getDebugLoc(); 385 386 if (!hasReservedCallFrame(MF)) { 387 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and 388 // ADJCALLSTACKUP must be converted to instructions manipulating the stack 389 // pointer. This is necessary when there is a variable length stack 390 // allocation (e.g. alloca), which means it's not possible to allocate 391 // space for outgoing arguments from within the function prologue. 392 int64_t Amount = MI->getOperand(0).getImm(); 393 394 if (Amount != 0) { 395 // Ensure the stack remains aligned after adjustment. 396 Amount = alignSPAdjust(Amount); 397 398 if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN) 399 Amount = -Amount; 400 401 adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); 402 } 403 } 404 405 return MBB.erase(MI); 406 } 407