LLVM  13.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  assert(checkAllSuperRegsMarked(Reserved));
105  return Reserved;
106 }
107 
109  MCRegister PhysReg) const {
110  return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
111 }
112 
114  return PhysReg == RISCV::X0;
115 }
116 
118  return CSR_NoRegs_RegMask;
119 }
120 
121 // Frame indexes representing locations of CSRs which are given a fixed location
122 // by save/restore libcalls.
123 static const std::map<unsigned, int> FixedCSRFIMap = {
124  {/*ra*/ RISCV::X1, -1},
125  {/*s0*/ RISCV::X8, -2},
126  {/*s1*/ RISCV::X9, -3},
127  {/*s2*/ RISCV::X18, -4},
128  {/*s3*/ RISCV::X19, -5},
129  {/*s4*/ RISCV::X20, -6},
130  {/*s5*/ RISCV::X21, -7},
131  {/*s6*/ RISCV::X22, -8},
132  {/*s7*/ RISCV::X23, -9},
133  {/*s8*/ RISCV::X24, -10},
134  {/*s9*/ RISCV::X25, -11},
135  {/*s10*/ RISCV::X26, -12},
136  {/*s11*/ RISCV::X27, -13}
137 };
138 
140  Register Reg,
141  int &FrameIdx) const {
142  const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
143  if (!RVFI->useSaveRestoreLibCalls(MF))
144  return false;
145 
146  auto FII = FixedCSRFIMap.find(Reg);
147  if (FII == FixedCSRFIMap.end())
148  return false;
149 
150  FrameIdx = FII->second;
151  return true;
152 }
153 
154 static bool isRVVWholeLoadStore(unsigned Opcode) {
155  switch (Opcode) {
156  default:
157  return false;
158  case RISCV::VS1R_V:
159  case RISCV::VS2R_V:
160  case RISCV::VS4R_V:
161  case RISCV::VS8R_V:
162  case RISCV::VL1RE8_V:
163  case RISCV::VL2RE8_V:
164  case RISCV::VL4RE8_V:
165  case RISCV::VL8RE8_V:
166  case RISCV::VL1RE16_V:
167  case RISCV::VL2RE16_V:
168  case RISCV::VL4RE16_V:
169  case RISCV::VL8RE16_V:
170  case RISCV::VL1RE32_V:
171  case RISCV::VL2RE32_V:
172  case RISCV::VL4RE32_V:
173  case RISCV::VL8RE32_V:
174  case RISCV::VL1RE64_V:
175  case RISCV::VL2RE64_V:
176  case RISCV::VL4RE64_V:
177  case RISCV::VL8RE64_V:
178  return true;
179  }
180 }
181 
183  int SPAdj, unsigned FIOperandNum,
184  RegScavenger *RS) const {
185  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
186 
187  MachineInstr &MI = *II;
188  MachineFunction &MF = *MI.getParent()->getParent();
190  const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
191  DebugLoc DL = MI.getDebugLoc();
192 
193  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
194  Register FrameReg;
196  getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
197  bool isRVV = RISCVVPseudosTable::getPseudoInfo(MI.getOpcode()) ||
198  isRVVWholeLoadStore(MI.getOpcode()) ||
199  TII->isRVVSpillForZvlsseg(MI.getOpcode());
200  if (!isRVV)
201  Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
202 
203  if (!isInt<32>(Offset.getFixed())) {
205  "Frame offsets outside of the signed 32-bit range not supported");
206  }
207 
208  MachineBasicBlock &MBB = *MI.getParent();
209  bool FrameRegIsKill = false;
210 
211  if (!isInt<12>(Offset.getFixed())) {
212  // The offset won't fit in an immediate, so use a scratch register instead
213  // Modify Offset and FrameReg appropriately
214  Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
215  TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
216  if (MI.getOpcode() == RISCV::ADDI && !Offset.getScalable()) {
217  BuildMI(MBB, II, DL, TII->get(RISCV::ADD), MI.getOperand(0).getReg())
218  .addReg(FrameReg)
219  .addReg(ScratchReg, RegState::Kill);
220  MI.eraseFromParent();
221  return;
222  }
223  BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
224  .addReg(FrameReg)
225  .addReg(ScratchReg, RegState::Kill);
226  Offset = StackOffset::get(0, Offset.getScalable());
227  FrameReg = ScratchReg;
228  FrameRegIsKill = true;
229  }
230 
231  if (!Offset.getScalable()) {
232  // Offset = (fixed offset, 0)
233  MI.getOperand(FIOperandNum)
234  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
235  if (!isRVV)
236  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
237  else {
238  if (Offset.getFixed()) {
239  Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
240  BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), ScratchReg)
241  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
242  .addImm(Offset.getFixed());
243  MI.getOperand(FIOperandNum)
244  .ChangeToRegister(ScratchReg, false, false, true);
245  }
246  }
247  } else {
248  // Offset = (fixed offset, scalable offset)
249  unsigned Opc = RISCV::ADD;
250  int64_t ScalableValue = Offset.getScalable();
251  if (ScalableValue < 0) {
252  ScalableValue = -ScalableValue;
253  Opc = RISCV::SUB;
254  }
255 
256  // 1. Get vlenb && multiply vlen with number of vector register.
257  Register FactorRegister =
258  TII->getVLENFactoredAmount(MF, MBB, II, ScalableValue);
259 
260  // 2. Calculate address: FrameReg + result of multiply
261  if (MI.getOpcode() == RISCV::ADDI && !Offset.getFixed()) {
262  BuildMI(MBB, II, DL, TII->get(Opc), MI.getOperand(0).getReg())
263  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
264  .addReg(FactorRegister, RegState::Kill);
265  MI.eraseFromParent();
266  return;
267  }
268  Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
269  BuildMI(MBB, II, DL, TII->get(Opc), VL)
270  .addReg(FrameReg, getKillRegState(FrameRegIsKill))
271  .addReg(FactorRegister, RegState::Kill);
272 
273  if (isRVV && Offset.getFixed()) {
274  // Scalable load/store has no immediate argument. We need to add the
275  // fixed part into the load/store base address.
276  BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), VL)
277  .addReg(VL)
278  .addImm(Offset.getFixed());
279  }
280 
281  // 3. Replace address register with calculated address register
282  MI.getOperand(FIOperandNum).ChangeToRegister(VL, false, false, true);
283  if (!isRVV)
284  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
285  }
286 
287  MachineFrameInfo &MFI = MF.getFrameInfo();
288  auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MI.getOpcode());
289  if (ZvlssegInfo) {
290  int64_t ScalableValue = MFI.getObjectSize(FrameIndex) / ZvlssegInfo->first;
291  Register FactorRegister =
292  TII->getVLENFactoredAmount(MF, MBB, II, ScalableValue);
293  MI.getOperand(FIOperandNum + 1)
294  .ChangeToRegister(FactorRegister, /*isDef=*/false);
295  }
296 }
297 
299  const TargetFrameLowering *TFI = getFrameLowering(MF);
300  return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;
301 }
302 
303 const uint32_t *
305  CallingConv::ID CC) const {
306  auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
307 
308  if (CC == CallingConv::GHC)
309  return CSR_NoRegs_RegMask;
310  switch (Subtarget.getTargetABI()) {
311  default:
312  llvm_unreachable("Unrecognized ABI");
313  case RISCVABI::ABI_ILP32:
314  case RISCVABI::ABI_LP64:
315  return CSR_ILP32_LP64_RegMask;
317  case RISCVABI::ABI_LP64F:
318  return CSR_ILP32F_LP64F_RegMask;
320  case RISCVABI::ABI_LP64D:
321  return CSR_ILP32D_LP64D_RegMask;
322  }
323 }
324 
325 const TargetRegisterClass *
327  const MachineFunction &) const {
328  if (RC == &RISCV::VMV0RegClass)
329  return &RISCV::VRRegClass;
330  return RC;
331 }
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:233
llvm::RISCVABI::ABI_LP64F
@ ABI_LP64F
Definition: RISCVBaseInfo.h:231
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
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:298
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:42
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:133
ErrorHandling.h
isRVVWholeLoadStore
static bool isRVVWholeLoadStore(unsigned Opcode)
Definition: RISCVRegisterInfo.cpp:154
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
TargetInstrInfo.h
llvm::Function::hasFnAttribute
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:345
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:226
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::RISCVABI::ABI_LP64
@ ABI_LP64
Definition: RISCVBaseInfo.h:230
llvm::RISCVRegisterInfo::isConstantPhysReg
bool isConstantPhysReg(MCRegister PhysReg) const override
Definition: RISCVRegisterInfo.cpp:113
llvm::CallingConv::GHC
@ GHC
Definition: CallingConv.h:51
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:653
llvm::RISCVRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Definition: RISCVRegisterInfo.cpp:304
llvm::RISCVRegisterInfo::getLargestLegalSuperClass
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override
Definition: RISCVRegisterInfo.cpp:326
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::RISCVFrameLowering
Definition: RISCVFrameLowering.h:22
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::RISCVABI::ABI_ILP32D
@ ABI_ILP32D
Definition: RISCVBaseInfo.h:228
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
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:140
llvm::BitVector
Definition: BitVector.h:74
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:49
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:555
llvm::RISCVRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: RISCVRegisterInfo.cpp:182
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::MachineFrameInfo::getObjectSize
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Definition: MachineFrameInfo.h:451
llvm::Function::getCallingConv
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:228
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::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:571
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:98
RISCV.h
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::RISCVInstrInfo
Definition: RISCVInstrInfo.h:27
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:219
FixedCSRFIMap
static const std::map< unsigned, int > FixedCSRFIMap
Definition: RISCVRegisterInfo.cpp:123
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:139
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:73
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::RISCVABI::ABI_LP64D
@ ABI_LP64D
Definition: RISCVBaseInfo.h:232
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:521
uint16_t
MachineFrameInfo.h
RISCVGenRegisterInfo
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:232
RISCVSubtarget.h
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:509
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
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:329
RISCVMachineFunctionInfo.h
llvm::PseudoProbeAttributes::Reserved
@ Reserved
llvm::RISCVABI::ABI_ILP32F
@ ABI_ILP32F
Definition: RISCVBaseInfo.h:227
llvm::RISCVRegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: RISCVRegisterInfo.cpp:117
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
llvm::RISCVFrameLowering::hasBP
bool hasBP(const MachineFunction &MF) const
Definition: RISCVFrameLowering.cpp:228
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:22
RISCVRegisterInfo.h
llvm::RISCVRegisterInfo::isAsmClobberable
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
Definition: RISCVRegisterInfo.cpp:108
llvm::StackOffset::get
static StackOffset get(ScalarTy Fixed, ScalarTy Scalable)
Definition: TypeSize.h:145