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 22 using namespace llvm; 23 24 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { 25 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 26 27 const MachineFrameInfo &MFI = MF.getFrameInfo(); 28 return MF.getTarget().Options.DisableFramePointerElim(MF) || 29 RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() || 30 MFI.isFrameAddressTaken(); 31 } 32 33 // Determines the size of the frame and maximum call frame size. 34 void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const { 35 MachineFrameInfo &MFI = MF.getFrameInfo(); 36 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 37 38 // Get the number of bytes to allocate from the FrameInfo. 39 uint64_t FrameSize = MFI.getStackSize(); 40 41 // Get the alignment. 42 uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment() 43 : getStackAlignment(); 44 45 // Make sure the frame is aligned. 46 FrameSize = alignTo(FrameSize, StackAlign); 47 48 // Update frame info. 49 MFI.setStackSize(FrameSize); 50 } 51 52 void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB, 53 MachineBasicBlock::iterator MBBI, 54 const DebugLoc &DL, unsigned DestReg, 55 unsigned SrcReg, int64_t Val, 56 MachineInstr::MIFlag Flag) const { 57 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 58 const RISCVInstrInfo *TII = STI.getInstrInfo(); 59 60 if (DestReg == SrcReg && Val == 0) 61 return; 62 63 if (isInt<12>(Val)) { 64 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg) 65 .addReg(SrcReg) 66 .addImm(Val) 67 .setMIFlag(Flag); 68 } else if (isInt<32>(Val)) { 69 unsigned Opc = RISCV::ADD; 70 bool isSub = Val < 0; 71 if (isSub) { 72 Val = -Val; 73 Opc = RISCV::SUB; 74 } 75 76 unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); 77 TII->movImm32(MBB, MBBI, DL, ScratchReg, Val, Flag); 78 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 79 .addReg(SrcReg) 80 .addReg(ScratchReg, RegState::Kill) 81 .setMIFlag(Flag); 82 } else { 83 report_fatal_error("adjustReg cannot yet handle adjustments >32 bits"); 84 } 85 } 86 87 // Returns the register used to hold the frame pointer. 88 static unsigned getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; } 89 90 // Returns the register used to hold the stack pointer. 91 static unsigned getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; } 92 93 void RISCVFrameLowering::emitPrologue(MachineFunction &MF, 94 MachineBasicBlock &MBB) const { 95 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 96 97 MachineFrameInfo &MFI = MF.getFrameInfo(); 98 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 99 MachineBasicBlock::iterator MBBI = MBB.begin(); 100 101 unsigned FPReg = getFPReg(STI); 102 unsigned SPReg = getSPReg(STI); 103 104 // Debug location must be unknown since the first debug location is used 105 // to determine the end of the prologue. 106 DebugLoc DL; 107 108 // Determine the correct frame layout 109 determineFrameLayout(MF); 110 111 // FIXME (note copied from Lanai): This appears to be overallocating. Needs 112 // investigation. Get the number of bytes to allocate from the FrameInfo. 113 uint64_t StackSize = MFI.getStackSize(); 114 115 // Early exit if there is no need to allocate on the stack 116 if (StackSize == 0 && !MFI.adjustsStack()) 117 return; 118 119 // Allocate space on the stack if necessary. 120 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); 121 122 // The frame pointer is callee-saved, and code has been generated for us to 123 // save it to the stack. We need to skip over the storing of callee-saved 124 // registers as the frame pointer must be modified after it has been saved 125 // to the stack, not before. 126 // FIXME: assumes exactly one instruction is used to save each callee-saved 127 // register. 128 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 129 std::advance(MBBI, CSI.size()); 130 131 // Generate new FP. 132 if (hasFP(MF)) 133 adjustReg(MBB, MBBI, DL, FPReg, SPReg, 134 StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); 135 } 136 137 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, 138 MachineBasicBlock &MBB) const { 139 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 140 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 141 MachineFrameInfo &MFI = MF.getFrameInfo(); 142 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 143 DebugLoc DL = MBBI->getDebugLoc(); 144 unsigned FPReg = getFPReg(STI); 145 unsigned SPReg = getSPReg(STI); 146 147 // Skip to before the restores of callee-saved registers 148 // FIXME: assumes exactly one instruction is used to restore each 149 // callee-saved register. 150 auto LastFrameDestroy = std::prev(MBBI, MFI.getCalleeSavedInfo().size()); 151 152 uint64_t StackSize = MFI.getStackSize(); 153 154 // Restore the stack pointer using the value of the frame pointer. Only 155 // necessary if the stack pointer was modified, meaning the stack size is 156 // unknown. 157 if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) { 158 assert(hasFP(MF) && "frame pointer should not have been eliminated"); 159 adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, 160 -StackSize + RVFI->getVarArgsSaveSize(), 161 MachineInstr::FrameDestroy); 162 } 163 164 // Deallocate stack 165 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); 166 } 167 168 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, 169 int FI, 170 unsigned &FrameReg) const { 171 const MachineFrameInfo &MFI = MF.getFrameInfo(); 172 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 173 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 174 175 // Callee-saved registers should be referenced relative to the stack 176 // pointer (positive offset), otherwise use the frame pointer (negative 177 // offset). 178 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 179 int MinCSFI = 0; 180 int MaxCSFI = -1; 181 182 int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + 183 MFI.getOffsetAdjustment(); 184 185 if (CSI.size()) { 186 MinCSFI = CSI[0].getFrameIdx(); 187 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 188 } 189 190 if (FI >= MinCSFI && FI <= MaxCSFI) { 191 FrameReg = RISCV::X2; 192 Offset += MF.getFrameInfo().getStackSize(); 193 } else { 194 FrameReg = RI->getFrameRegister(MF); 195 if (hasFP(MF)) 196 Offset += RVFI->getVarArgsSaveSize(); 197 else 198 Offset += MF.getFrameInfo().getStackSize(); 199 } 200 return Offset; 201 } 202 203 void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, 204 BitVector &SavedRegs, 205 RegScavenger *RS) const { 206 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 207 // Unconditionally spill RA and FP only if the function uses a frame 208 // pointer. 209 if (hasFP(MF)) { 210 SavedRegs.set(RISCV::X1); 211 SavedRegs.set(RISCV::X8); 212 } 213 214 // If interrupt is enabled and there are calls in the handler, 215 // unconditionally save all Caller-saved registers and 216 // all FP registers, regardless whether they are used. 217 MachineFrameInfo &MFI = MF.getFrameInfo(); 218 219 if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) { 220 221 static const MCPhysReg CSRegs[] = { RISCV::X1, /* ra */ 222 RISCV::X5, RISCV::X6, RISCV::X7, /* t0-t2 */ 223 RISCV::X10, RISCV::X11, /* a0-a1, a2-a7 */ 224 RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17, 225 RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31, 0 /* t3-t6 */ 226 }; 227 228 for (unsigned i = 0; CSRegs[i]; ++i) 229 SavedRegs.set(CSRegs[i]); 230 231 if (MF.getSubtarget<RISCVSubtarget>().hasStdExtD() || 232 MF.getSubtarget<RISCVSubtarget>().hasStdExtF()) { 233 234 // If interrupt is enabled, this list contains all FP registers. 235 const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs(); 236 237 for (unsigned i = 0; Regs[i]; ++i) 238 if (RISCV::FPR32RegClass.contains(Regs[i]) || 239 RISCV::FPR64RegClass.contains(Regs[i])) 240 SavedRegs.set(Regs[i]); 241 } 242 } 243 } 244 245 void RISCVFrameLowering::processFunctionBeforeFrameFinalized( 246 MachineFunction &MF, RegScavenger *RS) const { 247 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 248 MachineFrameInfo &MFI = MF.getFrameInfo(); 249 const TargetRegisterClass *RC = &RISCV::GPRRegClass; 250 // estimateStackSize has been observed to under-estimate the final stack 251 // size, so give ourselves wiggle-room by checking for stack size 252 // representable an 11-bit signed field rather than 12-bits. 253 // FIXME: It may be possible to craft a function with a small stack that 254 // still needs an emergency spill slot for branch relaxation. This case 255 // would currently be missed. 256 if (!isInt<11>(MFI.estimateStackSize(MF))) { 257 int RegScavFI = MFI.CreateStackObject( 258 RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false); 259 RS->addScavengingFrameIndex(RegScavFI); 260 } 261 } 262 263 // Not preserve stack space within prologue for outgoing variables when the 264 // function contains variable size objects and let eliminateCallFramePseudoInstr 265 // preserve stack space for it. 266 bool RISCVFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 267 return !MF.getFrameInfo().hasVarSizedObjects(); 268 } 269 270 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. 271 MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr( 272 MachineFunction &MF, MachineBasicBlock &MBB, 273 MachineBasicBlock::iterator MI) const { 274 unsigned SPReg = RISCV::X2; 275 DebugLoc DL = MI->getDebugLoc(); 276 277 if (!hasReservedCallFrame(MF)) { 278 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and 279 // ADJCALLSTACKUP must be converted to instructions manipulating the stack 280 // pointer. This is necessary when there is a variable length stack 281 // allocation (e.g. alloca), which means it's not possible to allocate 282 // space for outgoing arguments from within the function prologue. 283 int64_t Amount = MI->getOperand(0).getImm(); 284 285 if (Amount != 0) { 286 // Ensure the stack remains aligned after adjustment. 287 Amount = alignSPAdjust(Amount); 288 289 if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN) 290 Amount = -Amount; 291 292 adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); 293 } 294 } 295 296 return MBB.erase(MI); 297 } 298