LLVM  16.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 
41  switch (Subtarget.getTargetABI()) {
42  default:
43  llvm_unreachable("Unrecognized ABI");
46  return CSR_ILP32S_LP64S_SaveList;
49  return CSR_ILP32F_LP64F_SaveList;
52  return CSR_ILP32D_LP64D_SaveList;
53  }
54 }
55 
56 const uint32_t *
58  CallingConv::ID CC) const {
59  auto &Subtarget = MF.getSubtarget<LoongArchSubtarget>();
60 
61  switch (Subtarget.getTargetABI()) {
62  default:
63  llvm_unreachable("Unrecognized ABI");
66  return CSR_ILP32S_LP64S_RegMask;
69  return CSR_ILP32F_LP64F_RegMask;
72  return CSR_ILP32D_LP64D_RegMask;
73  }
74 }
75 
77  return CSR_NoRegs_RegMask;
78 }
79 
82  const LoongArchFrameLowering *TFI = getFrameLowering(MF);
83  BitVector Reserved(getNumRegs());
84 
85  // Use markSuperRegs to ensure any register aliases are also reserved
86  markSuperRegs(Reserved, LoongArch::R0); // zero
87  markSuperRegs(Reserved, LoongArch::R2); // tp
88  markSuperRegs(Reserved, LoongArch::R3); // sp
89  markSuperRegs(Reserved, LoongArch::R21); // non-allocatable
90  if (TFI->hasFP(MF))
91  markSuperRegs(Reserved, LoongArch::R22); // fp
92  // Reserve the base register if we need to realign the stack and allocate
93  // variable-sized objects at runtime.
94  if (TFI->hasBP(MF))
95  markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp
96 
97  // FIXME: To avoid generating COPY instructions between CFRs, only use $fcc0.
98  // This is required to work around the fact that COPY instruction between CFRs
99  // is not provided in LoongArch.
101  for (size_t Reg = LoongArch::FCC1; Reg <= LoongArch::FCC7; ++Reg)
102  markSuperRegs(Reserved, Reg);
103 
104  assert(checkAllSuperRegsMarked(Reserved));
105  return Reserved;
106 }
107 
108 Register
110  const TargetFrameLowering *TFI = getFrameLowering(MF);
111  return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3;
112 }
113 
115  int SPAdj,
116  unsigned FIOperandNum,
117  RegScavenger *RS) const {
118  // TODO: this implementation is a temporary placeholder which does just
119  // enough to allow other aspects of code generation to be tested.
120 
121  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
122 
123  MachineInstr &MI = *II;
124  assert(MI.getOperand(FIOperandNum + 1).isImm() &&
125  "Unexpected FI-consuming insn");
126 
127  MachineBasicBlock &MBB = *MI.getParent();
128  MachineFunction &MF = *MI.getParent()->getParent();
131  const LoongArchInstrInfo *TII = STI.getInstrInfo();
133  DebugLoc DL = MI.getDebugLoc();
134  bool IsLA64 = STI.is64Bit();
135  unsigned MIOpc = MI.getOpcode();
136 
137  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
138  Register FrameReg;
139  StackOffset Offset =
140  TFI->getFrameIndexReference(MF, FrameIndex, FrameReg) +
141  StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
142 
143  bool FrameRegIsKill = false;
144 
145  if (!isInt<12>(Offset.getFixed())) {
146  unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W;
147  unsigned Add = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W;
148 
149  // The offset won't fit in an immediate, so use a scratch register instead.
150  // Modify Offset and FrameReg appropriately.
151  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
152  TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
153  if (MIOpc == Addi) {
154  BuildMI(MBB, II, DL, TII->get(Add), MI.getOperand(0).getReg())
155  .addReg(FrameReg)
156  .addReg(ScratchReg, RegState::Kill);
157  MI.eraseFromParent();
158  return true;
159  }
160  BuildMI(MBB, II, DL, TII->get(Add), ScratchReg)
161  .addReg(FrameReg)
162  .addReg(ScratchReg, RegState::Kill);
163  Offset = StackOffset::getFixed(0);
164  FrameReg = ScratchReg;
165  FrameRegIsKill = true;
166  }
167 
168  // Spill CFRs.
169  if (MIOpc == LoongArch::PseudoST_CFR) {
170  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
171  BuildMI(MBB, II, DL, TII->get(LoongArch::MOVCF2GR), ScratchReg)
172  .add(MI.getOperand(0));
173  BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::ST_D : LoongArch::ST_W))
174  .addReg(ScratchReg, RegState::Kill)
175  .addReg(FrameReg)
176  .addImm(Offset.getFixed());
177  MI.eraseFromParent();
178  return true;
179  }
180 
181  // Reload CFRs.
182  if (MIOpc == LoongArch::PseudoLD_CFR) {
183  Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
184  BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::LD_D : LoongArch::LD_W),
185  ScratchReg)
186  .addReg(FrameReg)
187  .addImm(Offset.getFixed());
188  BuildMI(MBB, II, DL, TII->get(LoongArch::MOVGR2CF))
189  .add(MI.getOperand(0))
190  .addReg(ScratchReg, RegState::Kill);
191  MI.eraseFromParent();
192  return true;
193  }
194 
195  MI.getOperand(FIOperandNum)
196  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
197  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
198  return false;
199 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
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:156
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
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:114
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:83
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
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:57
llvm::LoongArchRegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: LoongArchRegisterInfo.cpp:76
R2
#define R2(n)
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
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:84
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:657
llvm::LoongArchRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:109
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
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:257
LoongArch.h
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 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
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::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::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::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
llvm::LoongArchABI::ABI_LP64D
@ ABI_LP64D
Definition: LoongArchBaseInfo.h:53
LoongArchInstrInfo.h
llvm::LoongArchABI::getBPReg
MCRegister getBPReg()
Definition: LoongArchBaseInfo.cpp:36
LoongArchMCTargetDesc.h
llvm::LoongArchSubtarget::getInstrInfo
const LoongArchInstrInfo * getInstrInfo() const override
Definition: LoongArchSubtarget.h:73
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::PseudoProbeAttributes::Reserved
@ Reserved
llvm::LoongArchRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:81
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
MachineFunction.h
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