1 //===-- RISCVFrameLowering.cpp - RISCV 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 RISCV implementation of TargetFrameLowering class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "RISCVFrameLowering.h" 15 #include "RISCVMachineFunctionInfo.h" 16 #include "RISCVSubtarget.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineRegisterInfo.h" 21 #include "llvm/CodeGen/RegisterScavenging.h" 22 23 using namespace llvm; 24 25 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { return true; } 26 27 // Determines the size of the frame and maximum call frame size. 28 void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const { 29 MachineFrameInfo &MFI = MF.getFrameInfo(); 30 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 31 32 // Get the number of bytes to allocate from the FrameInfo. 33 uint64_t FrameSize = MFI.getStackSize(); 34 35 // Get the alignment. 36 uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment() 37 : getStackAlignment(); 38 39 // Get the maximum call frame size of all the calls. 40 uint64_t MaxCallFrameSize = MFI.getMaxCallFrameSize(); 41 42 // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so 43 // that allocations will be aligned. 44 if (MFI.hasVarSizedObjects()) 45 MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign); 46 47 // Update maximum call frame size. 48 MFI.setMaxCallFrameSize(MaxCallFrameSize); 49 50 // Include call frame size in total. 51 if (!(hasReservedCallFrame(MF) && MFI.adjustsStack())) 52 FrameSize += MaxCallFrameSize; 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, unsigned DestReg, 64 unsigned 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 if (isInt<32>(Val)) { 78 unsigned Opc = RISCV::ADD; 79 bool isSub = Val < 0; 80 if (isSub) { 81 Val = -Val; 82 Opc = RISCV::SUB; 83 } 84 85 unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); 86 TII->movImm32(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 } else { 92 report_fatal_error("adjustReg cannot yet handle adjustments >32 bits"); 93 } 94 } 95 96 // Returns the register used to hold the frame pointer. 97 static unsigned getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; } 98 99 // Returns the register used to hold the stack pointer. 100 static unsigned getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; } 101 102 void RISCVFrameLowering::emitPrologue(MachineFunction &MF, 103 MachineBasicBlock &MBB) const { 104 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 105 106 if (!hasFP(MF)) { 107 report_fatal_error( 108 "emitPrologue doesn't support framepointer-less functions"); 109 } 110 111 MachineFrameInfo &MFI = MF.getFrameInfo(); 112 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 113 MachineBasicBlock::iterator MBBI = MBB.begin(); 114 115 unsigned FPReg = getFPReg(STI); 116 unsigned SPReg = getSPReg(STI); 117 118 // Debug location must be unknown since the first debug location is used 119 // to determine the end of the prologue. 120 DebugLoc DL; 121 122 // Determine the correct frame layout 123 determineFrameLayout(MF); 124 125 // FIXME (note copied from Lanai): This appears to be overallocating. Needs 126 // investigation. Get the number of bytes to allocate from the FrameInfo. 127 uint64_t StackSize = MFI.getStackSize(); 128 129 // Early exit if there is no need to allocate on the stack 130 if (StackSize == 0 && !MFI.adjustsStack()) 131 return; 132 133 // Allocate space on the stack if necessary. 134 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); 135 136 // The frame pointer is callee-saved, and code has been generated for us to 137 // save it to the stack. We need to skip over the storing of callee-saved 138 // registers as the frame pointer must be modified after it has been saved 139 // to the stack, not before. 140 // FIXME: assumes exactly one instruction is used to save each callee-saved 141 // register. 142 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 143 std::advance(MBBI, CSI.size()); 144 145 // Generate new FP. 146 adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize - RVFI->getVarArgsSaveSize(), 147 MachineInstr::FrameSetup); 148 } 149 150 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, 151 MachineBasicBlock &MBB) const { 152 if (!hasFP(MF)) { 153 report_fatal_error( 154 "emitEpilogue doesn't support framepointer-less functions"); 155 } 156 157 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 158 const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 159 MachineFrameInfo &MFI = MF.getFrameInfo(); 160 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 161 DebugLoc DL = MBBI->getDebugLoc(); 162 unsigned FPReg = getFPReg(STI); 163 unsigned SPReg = getSPReg(STI); 164 165 // Skip to before the restores of callee-saved registers 166 // FIXME: assumes exactly one instruction is used to restore each 167 // callee-saved register. 168 MachineBasicBlock::iterator LastFrameDestroy = MBBI; 169 std::advance(LastFrameDestroy, -MFI.getCalleeSavedInfo().size()); 170 171 uint64_t StackSize = MFI.getStackSize(); 172 173 // Restore the stack pointer using the value of the frame pointer. Only 174 // necessary if the stack pointer was modified, meaning the stack size is 175 // unknown. 176 if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) { 177 adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, 178 -StackSize + RVFI->getVarArgsSaveSize(), 179 MachineInstr::FrameDestroy); 180 } 181 182 // Deallocate stack 183 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); 184 } 185 186 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, 187 int FI, 188 unsigned &FrameReg) const { 189 const MachineFrameInfo &MFI = MF.getFrameInfo(); 190 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 191 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); 192 193 // Callee-saved registers should be referenced relative to the stack 194 // pointer (positive offset), otherwise use the frame pointer (negative 195 // offset). 196 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 197 int MinCSFI = 0; 198 int MaxCSFI = -1; 199 200 int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + 201 MFI.getOffsetAdjustment(); 202 203 if (CSI.size()) { 204 MinCSFI = CSI[0].getFrameIdx(); 205 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 206 } 207 208 if (FI >= MinCSFI && FI <= MaxCSFI) { 209 FrameReg = RISCV::X2; 210 Offset += MF.getFrameInfo().getStackSize(); 211 } else { 212 FrameReg = RI->getFrameRegister(MF); 213 assert(hasFP(MF) && "Offset calculation incorrect if !hasFP"); 214 Offset += RVFI->getVarArgsSaveSize(); 215 } 216 return Offset; 217 } 218 219 void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, 220 BitVector &SavedRegs, 221 RegScavenger *RS) const { 222 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 223 // TODO: Once frame pointer elimination is implemented, don't 224 // unconditionally spill the frame pointer and return address. 225 SavedRegs.set(RISCV::X1); 226 SavedRegs.set(RISCV::X8); 227 } 228 229 void RISCVFrameLowering::processFunctionBeforeFrameFinalized( 230 MachineFunction &MF, RegScavenger *RS) const { 231 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 232 MachineFrameInfo &MFI = MF.getFrameInfo(); 233 const TargetRegisterClass *RC = &RISCV::GPRRegClass; 234 // estimateStackSize has been observed to under-estimate the final stack 235 // size, so give ourselves wiggle-room by checking for stack size 236 // representable an 11-bit signed field rather than 12-bits. 237 // FIXME: It may be possible to craft a function with a small stack that 238 // still needs an emergency spill slot for branch relaxation. This case 239 // would currently be missed. 240 if (!isInt<11>(MFI.estimateStackSize(MF))) { 241 int RegScavFI = MFI.CreateStackObject( 242 RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false); 243 RS->addScavengingFrameIndex(RegScavFI); 244 } 245 } 246