LLVM  17.0.0git
LoongArchRegisterInfo.cpp
Go to the documentation of this file.
1 //===- LoongArchRegisterInfo.cpp - LoongArch 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 LoongArch implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "LoongArchRegisterInfo.h"
15 #include "LoongArch.h"
16 #include "LoongArchInstrInfo.h"
17 #include "LoongArchSubtarget.h"
26 
27 using namespace llvm;
28 
29 #define GET_REGINFO_TARGET_DESC
30 #include "LoongArchGenRegisterInfo.inc"
31 
33  : LoongArchGenRegisterInfo(LoongArch::R1, /*DwarfFlavour*/ 0,
34  /*EHFlavor*/ 0,
35  /*PC*/ 0, HwMode) {}
36 
37 const MCPhysReg *
39  auto &Subtarget = MF->getSubtarget<LoongArchSubtarget>();
40 
42  return CSR_NoRegs_SaveList;
43  switch (Subtarget.getTargetABI()) {
44  default:
45  llvm_unreachable("Unrecognized ABI");
48  return CSR_ILP32S_LP64S_SaveList;
51  return CSR_ILP32F_LP64F_SaveList;
54  return CSR_ILP32D_LP64D_SaveList;
55  }
56 }
57 
58 const uint32_t *
60  CallingConv::ID CC) const {
61  auto &Subtarget = MF.getSubtarget<LoongArchSubtarget>();
62 
63  if (CC == CallingConv::GHC)
64  return CSR_NoRegs_RegMask;
65  switch (Subtarget.getTargetABI()) {
66  default:
67  llvm_unreachable("Unrecognized ABI");
70  return CSR_ILP32S_LP64S_RegMask;
73  return CSR_ILP32F_LP64F_RegMask;
76  return CSR_ILP32D_LP64D_RegMask;
77  }
78 }
79 
81  return CSR_NoRegs_RegMask;
82 }
83 
86  const LoongArchFrameLowering *TFI = getFrameLowering(MF);
87  BitVector Reserved(getNumRegs());
88 
89  // Use markSuperRegs to ensure any register aliases are also reserved
90  markSuperRegs(Reserved, LoongArch::R0); // zero
91  markSuperRegs(Reserved, LoongArch::R2); // tp
92  markSuperRegs(Reserved, LoongArch::R3); // sp
93  markSuperRegs(Reserved, LoongArch::R21); // non-allocatable
94  if (TFI->hasFP(MF))
95  markSuperRegs(Reserved, LoongArch::R22); // fp
96  // Reserve the base register if we need to realign the stack and allocate
97  // variable-sized objects at runtime.
98  if (TFI->hasBP(MF))
99  markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp
100 
101  // FIXME: To avoid generating COPY instructions between CFRs, only use $fcc0.
102  // This is required to work around the fact that COPY instruction between CFRs
103  // is not provided in LoongArch.
105  for (size_t Reg = LoongArch::FCC1; Reg <= LoongArch::FCC7; ++Reg)
106  markSuperRegs(Reserved, Reg);
107 
108  assert(checkAllSuperRegsMarked(Reserved));
109  return Reserved;
110 }
111 
112 Register
114  const TargetFrameLowering *TFI = getFrameLowering(MF);
115  return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3;
116 }
117 
119  int SPAdj,
120  unsigned FIOperandNum,
121  RegScavenger *RS) const {
122  // TODO: this implementation is a temporary placeholder which does just
123  // enough to allow other aspects of code generation to be tested.
124 
125  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
126 
127  MachineInstr &MI = *II;
128  assert(MI.getOperand(FIOperandNum + 1).isImm() &&
129  "Unexpected FI-consuming insn");
130 
131  MachineBasicBlock &MBB = *MI.getParent();
132  MachineFunction &MF = *MI.getParent()->getParent();
135  const LoongArchInstrInfo *TII = STI.getInstrInfo();
137  DebugLoc DL = MI.getDebugLoc();
138  bool IsLA64 = STI.is64Bit();
139  unsigned MIOpc = MI.getOpcode();
140 
141  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
142  Register FrameReg;
144  TFI->getFrameIndexReference(MF, FrameIndex, FrameReg) +
145  StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
146 
147  bool FrameRegIsKill = false;
148 
149  if (!isInt<12>(Offset.getFixed())) {
150  unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W;
151  unsigned Add = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W;
152 
153  // The offset won't fit in an immediate, so use a scratch register instead.
154  // Modify Offset and FrameReg appropriately.
155  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
156  TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
157  if (MIOpc == Addi) {
158  BuildMI(MBB, II, DL, TII->get(Add), MI.getOperand(0).getReg())
159  .addReg(FrameReg)
160  .addReg(ScratchReg, RegState::Kill);
161  MI.eraseFromParent();
162  return true;
163  }
164  BuildMI(MBB, II, DL, TII->get(Add), ScratchReg)
165  .addReg(FrameReg)
166  .addReg(ScratchReg, RegState::Kill);
168  FrameReg = ScratchReg;
169  FrameRegIsKill = true;
170  }
171 
172  // Spill CFRs.
173  if (MIOpc == LoongArch::PseudoST_CFR) {
174  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
175  BuildMI(MBB, II, DL, TII->get(LoongArch::MOVCF2GR), ScratchReg)
176  .add(MI.getOperand(0));
177  BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::ST_D : LoongArch::ST_W))
178  .addReg(ScratchReg, RegState::Kill)
179  .addReg(FrameReg)
180  .addImm(Offset.getFixed());
181  MI.eraseFromParent();
182  return true;
183  }
184 
185  // Reload CFRs.
186  if (MIOpc == LoongArch::PseudoLD_CFR) {
187  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
188  BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::LD_D : LoongArch::LD_W),
189  ScratchReg)
190  .addReg(FrameReg)
191  .addImm(Offset.getFixed());
192  BuildMI(MBB, II, DL, TII->get(LoongArch::MOVGR2CF))
193  .add(MI.getOperand(0))
194  .addReg(ScratchReg, RegState::Kill);
195  MI.eraseFromParent();
196  return true;
197  }
198 
199  MI.getOperand(FIOperandNum)
200  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
201  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
202  return false;
203 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::LoongArchABI::ABI_LP64S
@ ABI_LP64S
Definition: LoongArchBaseInfo.h:51
TargetFrameLowering.h
llvm::LoongArchRegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Definition: LoongArchRegisterInfo.cpp:38
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:157
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:51
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::LoongArchRegisterInfo::eliminateFrameIndex
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: LoongArchRegisterInfo.cpp:118
LoongArchRegisterInfo.h
llvm::LoongArchABI::ABI_ILP32D
@ ABI_ILP32D
Definition: LoongArchBaseInfo.h:50
ErrorHandling.h
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::LoongArchSubtarget::is64Bit
bool is64Bit() const
Definition: LoongArchSubtarget.h:84
llvm::LoongArchABI::ABI_LP64F
@ ABI_LP64F
Definition: LoongArchBaseInfo.h:52
TargetInstrInfo.h
llvm::LoongArchABI::ABI_ILP32F
@ ABI_ILP32F
Definition: LoongArchBaseInfo.h:49
LoongArchSubtarget.h
llvm::LoongArchRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Definition: LoongArchRegisterInfo.cpp:59
llvm::LoongArchRegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: LoongArchRegisterInfo.cpp:80
R2
#define R2(n)
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:682
llvm::LoongArchFrameLowering
Definition: LoongArchFrameLowering.h:21
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
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::LoongArchSubtarget::hasBasicF
bool hasBasicF() const
Definition: LoongArchSubtarget.h:85
llvm::BitVector
Definition: BitVector.h:75
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:94
LoongArchGenRegisterInfo
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:672
llvm::LoongArchRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:113
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::Function::getCallingConv
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:237
llvm::LoongArchSubtarget
Definition: LoongArchSubtarget.h:32
llvm::RegScavenger
Definition: RegisterScavenging.h:34
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LoongArchFrameLowering::hasBP
bool hasBP(const MachineFunction &MF) const
Definition: LoongArchFrameLowering.cpp:43
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
llvm::LoongArchRegisterInfo::LoongArchRegisterInfo
LoongArchRegisterInfo(unsigned HwMode)
Definition: LoongArchRegisterInfo.cpp:32
llvm::MachineFunction
Definition: MachineFunction.h:258
LoongArch.h
llvm::Offset
@ Offset
Definition: DWP.cpp:406
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
llvm::StackOffset
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:36
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::VariableID::Reserved
@ Reserved
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::LoongArchABI::ABI_ILP32S
@ ABI_ILP32S
Definition: LoongArchBaseInfo.h:48
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:638
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:96
uint16_t
MachineFrameInfo.h
llvm::TargetFrameLowering::getFrameIndexReference
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
Definition: TargetFrameLoweringImpl.cpp:50
llvm::LoongArchABI::ABI_LP64D
@ ABI_LP64D
Definition: LoongArchBaseInfo.h:53
LoongArchInstrInfo.h
llvm::LoongArchABI::getBPReg
MCRegister getBPReg()
Definition: LoongArchBaseInfo.cpp:36
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
LoongArchMCTargetDesc.h
llvm::LoongArchSubtarget::getInstrInfo
const LoongArchInstrInfo * getInstrInfo() const override
Definition: LoongArchSubtarget.h:74
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
MachineInstrBuilder.h
llvm::CallingConv::GHC
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition: CallingConv.h:50
llvm::LoongArchRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:85
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
MachineFunction.h
llvm::StackOffset::getFixed
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:52
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::LoongArchInstrInfo
Definition: LoongArchInstrInfo.h:26
llvm::LoongArchFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Definition: LoongArchFrameLowering.cpp:34