LLVM  14.0.0git
RISCVRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- RISCVRegisterInfo.cpp - RISCV Register 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 RISCV implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVRegisterInfo.h"
14 #include "RISCV.h"
16 #include "RISCVSubtarget.h"
24 
25 #define GET_REGINFO_TARGET_DESC
26 #include "RISCVGenRegisterInfo.inc"
27 
28 using namespace llvm;
29 
30 static_assert(RISCV::X1 == RISCV::X0 + 1, "Register list not consecutive");
31 static_assert(RISCV::X31 == RISCV::X0 + 31, "Register list not consecutive");
32 static_assert(RISCV::F1_H == RISCV::F0_H + 1, "Register list not consecutive");
33 static_assert(RISCV::F31_H == RISCV::F0_H + 31,
34  "Register list not consecutive");
35 static_assert(RISCV::F1_F == RISCV::F0_F + 1, "Register list not consecutive");
36 static_assert(RISCV::F31_F == RISCV::F0_F + 31,
37  "Register list not consecutive");
38 static_assert(RISCV::F1_D == RISCV::F0_D + 1, "Register list not consecutive");
39 static_assert(RISCV::F31_D == RISCV::F0_D + 31,
40  "Register list not consecutive");
41 static_assert(RISCV::V1 == RISCV::V0 + 1, "Register list not consecutive");
42 static_assert(RISCV::V31 == RISCV::V0 + 31, "Register list not consecutive");
43 
45  : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,
46  /*PC*/0, HwMode) {}
47 
48 const MCPhysReg *
50  auto &Subtarget = MF->getSubtarget<RISCVSubtarget>();
52  return CSR_NoRegs_SaveList;
53  if (MF->getFunction().hasFnAttribute("interrupt")) {
54  if (Subtarget.hasStdExtD())
55  return CSR_XLEN_F64_Interrupt_SaveList;
56  if (Subtarget.hasStdExtF())
57  return CSR_XLEN_F32_Interrupt_SaveList;
58  return CSR_Interrupt_SaveList;
59  }
60 
61  switch (Subtarget.getTargetABI()) {
62  default:
63  llvm_unreachable("Unrecognized ABI");
65  case RISCVABI::ABI_LP64:
66  return CSR_ILP32_LP64_SaveList;
69  return CSR_ILP32F_LP64F_SaveList;
72  return CSR_ILP32D_LP64D_SaveList;
73  }
74 }
75 
77  const RISCVFrameLowering *TFI = getFrameLowering(MF);
78  BitVector Reserved(getNumRegs());
79 
80  // Mark any registers requested to be reserved as such
81  for (size_t Reg = 0; Reg < getNumRegs(); Reg++) {
83  markSuperRegs(Reserved, Reg);
84  }
85 
86  // Use markSuperRegs to ensure any register aliases are also reserved
87  markSuperRegs(Reserved, RISCV::X0); // zero
88  markSuperRegs(Reserved, RISCV::X2); // sp
89  markSuperRegs(Reserved, RISCV::X3); // gp
90  markSuperRegs(Reserved, RISCV::X4); // tp
91  if (TFI->hasFP(MF))
92  markSuperRegs(Reserved, RISCV::X8); // fp
93  // Reserve the base register if we need to realign the stack and allocate
94  // variable-sized objects at runtime.
95  if (TFI->hasBP(MF))
96  markSuperRegs(Reserved, RISCVABI::getBPReg()); // bp
97 
98  // V registers for code generation. We handle them manually.
99  markSuperRegs(Reserved, RISCV::VL);
100  markSuperRegs(Reserved, RISCV::VTYPE);
101  markSuperRegs(Reserved, RISCV::VXSAT);
102  markSuperRegs(Reserved, RISCV::VXRM);
103 
104  // Floating point environment registers.
105  markSuperRegs(Reserved, RISCV::FRM);
106  markSuperRegs(Reserved, RISCV::FFLAGS);
107  markSuperRegs(Reserved, RISCV::FCSR);
108 
109  assert(checkAllSuperRegsMarked(Reserved));
110  return Reserved;
111 }
112 
114  MCRegister PhysReg) const {
115  return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
116 }
117 
119  return PhysReg == RISCV::X0;
120 }
121 
123  return CSR_NoRegs_RegMask;
124 }
125 
126 // Frame indexes representing locations of CSRs which are given a fixed location
127 // by save/restore libcalls.
128 static const std::map<unsigned, int> FixedCSRFIMap = {
129  {/*ra*/ RISCV::X1, -1},
130  {/*s0*/ RISCV::X8, -2},
131  {/*s1*/ RISCV::X9, -3},
132  {/*s2*/ RISCV::X18, -4},
133  {/*s3*/ RISCV::X19, -5},
134  {/*s4*/ RISCV::X20, -6},
135  {/*s5*/ RISCV::X21, -7},
136  {/*s6*/ RISCV::X22, -8},
137  {/*s7*/ RISCV::X23, -9},
138  {/*s8*/ RISCV::X24, -10},
139  {/*s9*/ RISCV::X25, -11},
140  {/*s10*/ RISCV::X26, -12},
141  {/*s11*/ RISCV::X27, -13}
142 };
143 
145  Register Reg,
146  int &FrameIdx) const {
147  const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
148  if (!RVFI->useSaveRestoreLibCalls(MF))
149  return false;
150 
151  auto FII = FixedCSRFIMap.find(Reg);
152  if (FII == FixedCSRFIMap.end())
153  return false;
154 
155  FrameIdx = FII->second;
156  return true;
157 }
158 
160  int SPAdj, unsigned FIOperandNum,
161  RegScavenger *RS) const {
162  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
163 
164  MachineInstr &MI = *II;
165  MachineFunction &MF = *MI.getParent()->getParent();
167  const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
168  DebugLoc DL = MI.getDebugLoc();
169 
170  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
171  Register FrameReg;
173  getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
174  bool IsRVVSpill = TII->isRVVSpill(MI, /*CheckFIs*/ false);
175  if (!IsRVVSpill)
176  Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
177 
178  if (!isInt<32>(Offset.getFixed())) {
180  "Frame offsets outside of the signed 32-bit range not supported");
181  }
182 
183  MachineBasicBlock &MBB = *MI.getParent();
184  bool FrameRegIsKill = false;
185 
186  // If required, pre-compute the scalable factor amount which will be used in
187  // later offset computation. Since this sequence requires up to two scratch
188  // registers -- after which one is made free -- this grants us better
189  // scavenging of scratch registers as only up to two are live at one time,
190  // rather than three.
191  Register ScalableFactorRegister;
192  unsigned ScalableAdjOpc = RISCV::ADD;
193  if (Offset.getScalable()) {
194  int64_t ScalableValue = Offset.getScalable();
195  if (ScalableValue < 0) {
196  ScalableValue = -ScalableValue;
197  ScalableAdjOpc = RISCV::SUB;
198  }
199  // 1. Get vlenb && multiply vlen with the number of vector registers.
200  ScalableFactorRegister =
201  TII->getVLENFactoredAmount(MF, MBB, II, DL, ScalableValue);
202  }
203 
204  if (!isInt<12>(Offset.getFixed())) {
205  // The offset won't fit in an immediate, so use a scratch register instead
206  // Modify Offset and FrameReg appropriately
207  Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
208  TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
209  if (MI.getOpcode() == RISCV::ADDI && !Offset.getScalable()) {
210  BuildMI(MBB, II, DL, TII->get(RISCV::ADD), MI.getOperand(0).getReg())
211  .addReg(FrameReg)
212  .addReg(ScratchReg, RegState::Kill);
213  MI.eraseFromParent();
214  return;
215  }
216  BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
217  .addReg(FrameReg)
218  .addReg(ScratchReg, RegState::Kill);
219  Offset = StackOffset::get(0, Offset.getScalable());
220  FrameReg = ScratchReg;
221  FrameRegIsKill = true;
222  }
223 
224  if (!Offset.getScalable()) {
225  // Offset = (fixed offset, 0)
226  MI.getOperand(FIOperandNum)
227  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
228  if (!IsRVVSpill)
229  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
230  else {
231  if (Offset.getFixed()) {
232  Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
233  BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), ScratchReg)
234  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
235  .addImm(Offset.getFixed());
236  MI.getOperand(FIOperandNum)
237  .ChangeToRegister(ScratchReg, false, false, true);
238  }
239  }
240  } else {
241  // Offset = (fixed offset, scalable offset)
242  // Step 1, the scalable offset, has already been computed.
243  assert(ScalableFactorRegister &&
244  "Expected pre-computation of scalable factor in earlier step");
245 
246  // 2. Calculate address: FrameReg + result of multiply
247  if (MI.getOpcode() == RISCV::ADDI && !Offset.getFixed()) {
248  BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), MI.getOperand(0).getReg())
249  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
250  .addReg(ScalableFactorRegister, RegState::Kill);
251  MI.eraseFromParent();
252  return;
253  }
254  Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
255  BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), VL)
256  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
257  .addReg(ScalableFactorRegister, RegState::Kill);
258 
259  if (IsRVVSpill && Offset.getFixed()) {
260  // Scalable load/store has no immediate argument. We need to add the
261  // fixed part into the load/store base address.
262  BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), VL)
263  .addReg(VL)
264  .addImm(Offset.getFixed());
265  }
266 
267  // 3. Replace address register with calculated address register
268  MI.getOperand(FIOperandNum).ChangeToRegister(VL, false, false, true);
269  if (!IsRVVSpill)
270  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
271  }
272 
273  auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MI.getOpcode());
274  if (ZvlssegInfo) {
275  Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
276  BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL);
277  uint32_t ShiftAmount = Log2_32(ZvlssegInfo->second);
278  if (ShiftAmount != 0)
279  BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL)
280  .addReg(VL)
281  .addImm(ShiftAmount);
282  // The last argument of pseudo spilling opcode for zvlsseg is the length of
283  // one element of zvlsseg types. For example, for vint32m2x2_t, it will be
284  // the length of vint32m2_t.
285  MI.getOperand(FIOperandNum + 1).ChangeToRegister(VL, /*isDef=*/false);
286  }
287 }
288 
290  const TargetFrameLowering *TFI = getFrameLowering(MF);
291  return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;
292 }
293 
294 const uint32_t *
296  CallingConv::ID CC) const {
297  auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
298 
299  if (CC == CallingConv::GHC)
300  return CSR_NoRegs_RegMask;
301  switch (Subtarget.getTargetABI()) {
302  default:
303  llvm_unreachable("Unrecognized ABI");
304  case RISCVABI::ABI_ILP32:
305  case RISCVABI::ABI_LP64:
306  return CSR_ILP32_LP64_RegMask;
308  case RISCVABI::ABI_LP64F:
309  return CSR_ILP32F_LP64F_RegMask;
311  case RISCVABI::ABI_LP64D:
312  return CSR_ILP32D_LP64D_RegMask;
313  }
314 }
315 
316 const TargetRegisterClass *
318  const MachineFunction &) const {
319  if (RC == &RISCV::VMV0RegClass)
320  return &RISCV::VRRegClass;
321  return RC;
322 }
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:240
llvm::RISCVABI::ABI_LP64F
@ ABI_LP64F
Definition: RISCVBaseInfo.h:296
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
TargetFrameLowering.h
llvm::RISCVRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: RISCVRegisterInfo.cpp:289
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::RISCVRegisterInfo::RISCVRegisterInfo
RISCVRegisterInfo(unsigned HwMode)
Definition: RISCVRegisterInfo.cpp:44
llvm::RISCVSubtarget::isRegisterReservedByUser
bool isRegisterReservedByUser(Register i) const
Definition: RISCVSubtarget.h:134
ErrorHandling.h
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
TargetInstrInfo.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::RISCVABI::getBPReg
MCRegister getBPReg()
Definition: RISCVBaseInfo.cpp:81
llvm::RISCVRegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Definition: RISCVRegisterInfo.cpp:49
llvm::RISCVABI::ABI_ILP32
@ ABI_ILP32
Definition: RISCVBaseInfo.h:291
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
llvm::RISCVABI::ABI_LP64
@ ABI_LP64
Definition: RISCVBaseInfo.h:295
llvm::RISCVRegisterInfo::isConstantPhysReg
bool isConstantPhysReg(MCRegister PhysReg) const override
Definition: RISCVRegisterInfo.cpp:118
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:724
llvm::RISCVRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Definition: RISCVRegisterInfo.cpp:295
llvm::RISCVRegisterInfo::getLargestLegalSuperClass
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override
Definition: RISCVRegisterInfo.cpp:317
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::RISCVFrameLowering
Definition: RISCVFrameLowering.h:22
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::Log2_32
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:596
llvm::RISCVABI::ABI_ILP32D
@ ABI_ILP32D
Definition: RISCVBaseInfo.h:293
llvm::RISCVRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: RISCVRegisterInfo.cpp:76
llvm::TargetFrameLowering::hasFP
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::BitVector
Definition: BitVector.h:74
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::Function::hasFnAttribute
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:626
llvm::RISCVRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: RISCVRegisterInfo.cpp:159
llvm::isInt< 32 >
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:373
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::Function::getCallingConv
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:239
llvm::RegScavenger
Definition: RegisterScavenging.h:34
llvm::RISCVMachineFunctionInfo
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
Definition: RISCVMachineFunctionInfo.h:24
llvm::RISCVSubtarget
Definition: RISCVSubtarget.h:35
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
RISCV.h
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::RISCVInstrInfo
Definition: RISCVInstrInfo.h:43
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
uint32_t
llvm::StackOffset
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
Definition: TypeSize.h:134
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::RISCVFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Definition: RISCVFrameLowering.cpp:223
FixedCSRFIMap
static const std::map< unsigned, int > FixedCSRFIMap
Definition: RISCVRegisterInfo.cpp:128
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::RISCVRegisterInfo::hasReservedSpillSlot
bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg, int &FrameIdx) const override
Definition: RISCVRegisterInfo.cpp:144
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::RISCVABI::ABI_LP64D
@ ABI_LP64D
Definition: RISCVBaseInfo.h:297
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:592
uint16_t
MachineFrameInfo.h
RISCVGenRegisterInfo
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
RISCVSubtarget.h
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
RISCVMachineFunctionInfo.h
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
llvm::RISCVABI::ABI_ILP32F
@ ABI_ILP32F
Definition: RISCVBaseInfo.h:292
llvm::RISCVRegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: RISCVRegisterInfo.cpp:122
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
llvm::RISCVFrameLowering::hasBP
bool hasBP(const MachineFunction &MF) const
Definition: RISCVFrameLowering.cpp:232
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::CallingConv::GHC
@ GHC
Definition: CallingConv.h:51
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:23
RISCVRegisterInfo.h
llvm::RISCVRegisterInfo::isAsmClobberable
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
Definition: RISCVRegisterInfo.cpp:113
llvm::StackOffset::get
static StackOffset get(ScalarTy Fixed, ScalarTy Scalable)
Definition: TypeSize.h:145