LLVM  9.0.0svn
RISCVFrameLowering.cpp
Go to the documentation of this file.
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"
15 #include "RISCVSubtarget.h"
21 #include "llvm/MC/MCDwarf.h"
22 
23 using namespace llvm;
24 
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();
38 
39  // Get the number of bytes to allocate from the FrameInfo.
40  uint64_t FrameSize = MFI.getStackSize();
41 
42  // Get the alignment.
43  uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
45 
46  // Make sure the frame is aligned.
47  FrameSize = alignTo(FrameSize, StackAlign);
48 
49  // Update frame info.
50  MFI.setStackSize(FrameSize);
51 }
52 
53 void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB,
55  const DebugLoc &DL, unsigned DestReg,
56  unsigned SrcReg, int64_t Val,
57  MachineInstr::MIFlag Flag) const {
60 
61  if (DestReg == SrcReg && Val == 0)
62  return;
63 
64  if (isInt<12>(Val)) {
65  BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
66  .addReg(SrcReg)
67  .addImm(Val)
68  .setMIFlag(Flag);
69  } else if (isInt<32>(Val)) {
70  unsigned Opc = RISCV::ADD;
71  bool isSub = Val < 0;
72  if (isSub) {
73  Val = -Val;
74  Opc = RISCV::SUB;
75  }
76 
77  unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
78  TII->movImm32(MBB, MBBI, DL, ScratchReg, Val, Flag);
79  BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
80  .addReg(SrcReg)
81  .addReg(ScratchReg, RegState::Kill)
82  .setMIFlag(Flag);
83  } else {
84  report_fatal_error("adjustReg cannot yet handle adjustments >32 bits");
85  }
86 }
87 
88 // Returns the register used to hold the frame pointer.
89 static unsigned getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; }
90 
91 // Returns the register used to hold the stack pointer.
92 static unsigned getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
93 
95  MachineBasicBlock &MBB) const {
96  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
97 
98  MachineFrameInfo &MFI = MF.getFrameInfo();
99  auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
100  const RISCVRegisterInfo *RI = STI.getRegisterInfo();
101  const RISCVInstrInfo *TII = STI.getInstrInfo();
102  MachineBasicBlock::iterator MBBI = MBB.begin();
103 
104  unsigned FPReg = getFPReg(STI);
105  unsigned SPReg = getSPReg(STI);
106 
107  // Debug location must be unknown since the first debug location is used
108  // to determine the end of the prologue.
109  DebugLoc DL;
110 
111  // Determine the correct frame layout
112  determineFrameLayout(MF);
113 
114  // FIXME (note copied from Lanai): This appears to be overallocating. Needs
115  // investigation. Get the number of bytes to allocate from the FrameInfo.
116  uint64_t StackSize = MFI.getStackSize();
117 
118  // Early exit if there is no need to allocate on the stack
119  if (StackSize == 0 && !MFI.adjustsStack())
120  return;
121 
122  // Allocate space on the stack if necessary.
123  adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
124 
125  // Emit ".cfi_def_cfa_offset StackSize"
126  unsigned CFIIndex = MF.addFrameInst(
127  MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
128  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
129  .addCFIIndex(CFIIndex);
130 
131  // The frame pointer is callee-saved, and code has been generated for us to
132  // save it to the stack. We need to skip over the storing of callee-saved
133  // registers as the frame pointer must be modified after it has been saved
134  // to the stack, not before.
135  // FIXME: assumes exactly one instruction is used to save each callee-saved
136  // register.
137  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
138  std::advance(MBBI, CSI.size());
139 
140  // Iterate over list of callee-saved registers and emit .cfi_offset
141  // directives.
142  for (const auto &Entry : CSI) {
143  int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx());
144  unsigned Reg = Entry.getReg();
145  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
146  nullptr, RI->getDwarfRegNum(Reg, true), Offset));
147  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
148  .addCFIIndex(CFIIndex);
149  }
150 
151  // Generate new FP.
152  if (hasFP(MF)) {
153  adjustReg(MBB, MBBI, DL, FPReg, SPReg,
154  StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup);
155 
156  // Emit ".cfi_def_cfa $fp, 0"
157  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
158  nullptr, RI->getDwarfRegNum(FPReg, true), 0));
159  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
160  .addCFIIndex(CFIIndex);
161  }
162 }
163 
165  MachineBasicBlock &MBB) const {
167  const RISCVRegisterInfo *RI = STI.getRegisterInfo();
168  MachineFrameInfo &MFI = MF.getFrameInfo();
169  auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
170  DebugLoc DL = MBBI->getDebugLoc();
171  const RISCVInstrInfo *TII = STI.getInstrInfo();
172  unsigned FPReg = getFPReg(STI);
173  unsigned SPReg = getSPReg(STI);
174 
175  // Skip to before the restores of callee-saved registers
176  // FIXME: assumes exactly one instruction is used to restore each
177  // callee-saved register.
178  auto LastFrameDestroy = std::prev(MBBI, MFI.getCalleeSavedInfo().size());
179 
180  uint64_t StackSize = MFI.getStackSize();
181  uint64_t FPOffset = StackSize - RVFI->getVarArgsSaveSize();
182 
183  // Restore the stack pointer using the value of the frame pointer. Only
184  // necessary if the stack pointer was modified, meaning the stack size is
185  // unknown.
186  if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
187  assert(hasFP(MF) && "frame pointer should not have been eliminated");
188  adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -FPOffset,
190  }
191 
192  if (hasFP(MF)) {
193  // To find the instruction restoring FP from stack.
194  for (auto &I = LastFrameDestroy; I != MBBI; ++I) {
195  if (I->mayLoad() && I->getOperand(0).isReg()) {
196  unsigned DestReg = I->getOperand(0).getReg();
197  if (DestReg == FPReg) {
198  // If there is frame pointer, after restoring $fp registers, we
199  // need adjust CFA to ($sp - FPOffset).
200  // Emit ".cfi_def_cfa $sp, -FPOffset"
201  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
202  nullptr, RI->getDwarfRegNum(SPReg, true), -FPOffset));
203  BuildMI(MBB, std::next(I), DL,
204  TII->get(TargetOpcode::CFI_INSTRUCTION))
205  .addCFIIndex(CFIIndex);
206  break;
207  }
208  }
209  }
210  }
211 
212  // Add CFI directives for callee-saved registers.
213  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
214  // Iterate over list of callee-saved registers and emit .cfi_restore
215  // directives.
216  for (const auto &Entry : CSI) {
217  unsigned Reg = Entry.getReg();
218  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
219  nullptr, RI->getDwarfRegNum(Reg, true)));
220  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
221  .addCFIIndex(CFIIndex);
222  }
223 
224  // Deallocate stack
225  adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy);
226 
227  // After restoring $sp, we need to adjust CFA to $(sp + 0)
228  // Emit ".cfi_def_cfa_offset 0"
229  unsigned CFIIndex =
231  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
232  .addCFIIndex(CFIIndex);
233 }
234 
236  int FI,
237  unsigned &FrameReg) const {
238  const MachineFrameInfo &MFI = MF.getFrameInfo();
240  const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
241 
242  // Callee-saved registers should be referenced relative to the stack
243  // pointer (positive offset), otherwise use the frame pointer (negative
244  // offset).
245  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
246  int MinCSFI = 0;
247  int MaxCSFI = -1;
248 
249  int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() +
250  MFI.getOffsetAdjustment();
251 
252  if (CSI.size()) {
253  MinCSFI = CSI[0].getFrameIdx();
254  MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
255  }
256 
257  if (FI >= MinCSFI && FI <= MaxCSFI) {
258  FrameReg = RISCV::X2;
259  Offset += MF.getFrameInfo().getStackSize();
260  } else {
261  FrameReg = RI->getFrameRegister(MF);
262  if (hasFP(MF))
263  Offset += RVFI->getVarArgsSaveSize();
264  else
265  Offset += MF.getFrameInfo().getStackSize();
266  }
267  return Offset;
268 }
269 
271  BitVector &SavedRegs,
272  RegScavenger *RS) const {
274  // Unconditionally spill RA and FP only if the function uses a frame
275  // pointer.
276  if (hasFP(MF)) {
277  SavedRegs.set(RISCV::X1);
278  SavedRegs.set(RISCV::X8);
279  }
280 
281  // If interrupt is enabled and there are calls in the handler,
282  // unconditionally save all Caller-saved registers and
283  // all FP registers, regardless whether they are used.
284  MachineFrameInfo &MFI = MF.getFrameInfo();
285 
286  if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {
287 
288  static const MCPhysReg CSRegs[] = { RISCV::X1, /* ra */
289  RISCV::X5, RISCV::X6, RISCV::X7, /* t0-t2 */
290  RISCV::X10, RISCV::X11, /* a0-a1, a2-a7 */
291  RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17,
292  RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31, 0 /* t3-t6 */
293  };
294 
295  for (unsigned i = 0; CSRegs[i]; ++i)
296  SavedRegs.set(CSRegs[i]);
297 
298  if (MF.getSubtarget<RISCVSubtarget>().hasStdExtD() ||
299  MF.getSubtarget<RISCVSubtarget>().hasStdExtF()) {
300 
301  // If interrupt is enabled, this list contains all FP registers.
302  const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs();
303 
304  for (unsigned i = 0; Regs[i]; ++i)
305  if (RISCV::FPR32RegClass.contains(Regs[i]) ||
306  RISCV::FPR64RegClass.contains(Regs[i]))
307  SavedRegs.set(Regs[i]);
308  }
309  }
310 }
311 
313  MachineFunction &MF, RegScavenger *RS) const {
314  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
315  MachineFrameInfo &MFI = MF.getFrameInfo();
316  const TargetRegisterClass *RC = &RISCV::GPRRegClass;
317  // estimateStackSize has been observed to under-estimate the final stack
318  // size, so give ourselves wiggle-room by checking for stack size
319  // representable an 11-bit signed field rather than 12-bits.
320  // FIXME: It may be possible to craft a function with a small stack that
321  // still needs an emergency spill slot for branch relaxation. This case
322  // would currently be missed.
323  if (!isInt<11>(MFI.estimateStackSize(MF))) {
324  int RegScavFI = MFI.CreateStackObject(
325  RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
326  RS->addScavengingFrameIndex(RegScavFI);
327  }
328 }
329 
330 // Not preserve stack space within prologue for outgoing variables when the
331 // function contains variable size objects and let eliminateCallFramePseudoInstr
332 // preserve stack space for it.
334  return !MF.getFrameInfo().hasVarSizedObjects();
335 }
336 
337 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
341  unsigned SPReg = RISCV::X2;
342  DebugLoc DL = MI->getDebugLoc();
343 
344  if (!hasReservedCallFrame(MF)) {
345  // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
346  // ADJCALLSTACKUP must be converted to instructions manipulating the stack
347  // pointer. This is necessary when there is a variable length stack
348  // allocation (e.g. alloca), which means it's not possible to allocate
349  // space for outgoing arguments from within the function prologue.
350  int64_t Amount = MI->getOperand(0).getImm();
351 
352  if (Amount != 0) {
353  // Ensure the stack remains aligned after adjustment.
354  Amount = alignSPAdjust(Amount);
355 
356  if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
357  Amount = -Amount;
358 
359  adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags);
360  }
361  }
362 
363  return MBB.erase(MI);
364 }
BitVector & set()
Definition: BitVector.h:397
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:504
unsigned Reg
const RISCVRegisterInfo * getRegisterInfo() const override
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
A debug info location.
Definition: DebugLoc.h:33
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:684
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:491
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
return AArch64::GPR64RegClass contains(Reg)
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
static unsigned getSPReg(const RISCVSubtarget &STI)
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment. ...
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
void movImm32(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:117
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register, int Offset)
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it...
Definition: MCDwarf.h:477
static unsigned getFPReg(const RISCVSubtarget &STI)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void setStackSize(uint64_t Size)
Set the size of the stack.
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register)
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
Definition: MCDwarf.h:537
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasStdExtD() const
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:308
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:58
int getOffsetAdjustment() const
Return the correction for frame offsets.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const RISCVSubtarget & STI
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
const RISCVInstrInfo * getInstrInfo() const override
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
IRTranslator LLVM IR MI
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasCalls() const
Return true if the current function has any function calls.