LLVM  14.0.0git
MipsSERegisterInfo.cpp
Go to the documentation of this file.
1 //===-- MipsSERegisterInfo.cpp - MIPS32/64 Register 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 MIPS32/64 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsSERegisterInfo.h"
15 #include "Mips.h"
16 #include "MipsMachineFunction.h"
17 #include "MipsSEInstrInfo.h"
18 #include "MipsSubtarget.h"
19 #include "MipsTargetMachine.h"
20 #include "llvm/ADT/STLExtras.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DebugInfo.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/Debug.h"
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "mips-reg-info"
40 
42 
45  return true;
46 }
47 
50  return true;
51 }
52 
53 const TargetRegisterClass *
55  if (Size == 4)
56  return &Mips::GPR32RegClass;
57 
58  assert(Size == 8);
59  return &Mips::GPR64RegClass;
60 }
61 
62 /// Get the size of the offset supported by the given load/store/inline asm.
63 /// The result includes the effects of any scale factors applied to the
64 /// instruction immediate.
65 static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode,
66  MachineOperand MO) {
67  switch (Opcode) {
68  case Mips::LD_B:
69  case Mips::ST_B:
70  return 10;
71  case Mips::LD_H:
72  case Mips::ST_H:
73  return 10 + 1 /* scale factor */;
74  case Mips::LD_W:
75  case Mips::ST_W:
76  return 10 + 2 /* scale factor */;
77  case Mips::LD_D:
78  case Mips::ST_D:
79  return 10 + 3 /* scale factor */;
80  case Mips::LL:
81  case Mips::LL64:
82  case Mips::LLD:
83  case Mips::LLE:
84  case Mips::SC:
85  case Mips::SC64:
86  case Mips::SCD:
87  case Mips::SCE:
88  return 16;
89  case Mips::LLE_MM:
90  case Mips::LL_MM:
91  case Mips::SCE_MM:
92  case Mips::SC_MM:
93  return 12;
94  case Mips::LL64_R6:
95  case Mips::LL_R6:
96  case Mips::LLD_R6:
97  case Mips::SC64_R6:
98  case Mips::SCD_R6:
99  case Mips::SC_R6:
100  case Mips::LL_MMR6:
101  case Mips::SC_MMR6:
102  return 9;
103  case Mips::INLINEASM: {
104  unsigned ConstraintID = InlineAsm::getMemoryConstraintID(MO.getImm());
105  switch (ConstraintID) {
107  const MipsSubtarget &Subtarget = MO.getParent()
108  ->getParent()
109  ->getParent()
111  if (Subtarget.inMicroMipsMode())
112  return 12;
113 
114  if (Subtarget.hasMips32r6())
115  return 9;
116 
117  return 16;
118  }
119  default:
120  return 16;
121  }
122  }
123  default:
124  return 16;
125  }
126 }
127 
128 /// Get the scale factor applied to the immediate in the given load/store.
129 static inline unsigned getLoadStoreOffsetAlign(const unsigned Opcode) {
130  switch (Opcode) {
131  case Mips::LD_H:
132  case Mips::ST_H:
133  return 2;
134  case Mips::LD_W:
135  case Mips::ST_W:
136  return 4;
137  case Mips::LD_D:
138  case Mips::ST_D:
139  return 8;
140  default:
141  return 1;
142  }
143 }
144 
145 void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
146  unsigned OpNo, int FrameIndex,
147  uint64_t StackSize,
148  int64_t SPOffset) const {
149  MachineInstr &MI = *II;
150  MachineFunction &MF = *MI.getParent()->getParent();
151  MachineFrameInfo &MFI = MF.getFrameInfo();
152  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
153 
154  MipsABIInfo ABI =
155  static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
156  const MipsRegisterInfo *RegInfo =
157  static_cast<const MipsRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
158 
159  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
160  int MinCSFI = 0;
161  int MaxCSFI = -1;
162 
163  if (CSI.size()) {
164  MinCSFI = CSI[0].getFrameIdx();
165  MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
166  }
167 
168  bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);
169  bool IsISRRegFI = MipsFI->isISRRegFI(FrameIndex);
170  // The following stack frame objects are always referenced relative to $sp:
171  // 1. Outgoing arguments.
172  // 2. Pointer to dynamically allocated stack space.
173  // 3. Locations for callee-saved registers.
174  // 4. Locations for eh data registers.
175  // 5. Locations for ISR saved Coprocessor 0 registers 12 & 14.
176  // Everything else is referenced relative to whatever register
177  // getFrameRegister() returns.
178  unsigned FrameReg;
179 
180  if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI ||
181  IsISRRegFI)
182  FrameReg = ABI.GetStackPtr();
183  else if (RegInfo->hasStackRealignment(MF)) {
185  FrameReg = ABI.GetBasePtr();
186  else if (MFI.isFixedObjectIndex(FrameIndex))
187  FrameReg = getFrameRegister(MF);
188  else
189  FrameReg = ABI.GetStackPtr();
190  } else
191  FrameReg = getFrameRegister(MF);
192 
193  // Calculate final offset.
194  // - There is no need to change the offset if the frame object is one of the
195  // following: an outgoing argument, pointer to a dynamically allocated
196  // stack space or a $gp restore location,
197  // - If the frame object is any of the following, its offset must be adjusted
198  // by adding the size of the stack:
199  // incoming argument, callee-saved register location or local variable.
200  bool IsKill = false;
201  int64_t Offset;
202 
203  Offset = SPOffset + (int64_t)StackSize;
204  Offset += MI.getOperand(OpNo + 1).getImm();
205 
206  LLVM_DEBUG(errs() << "Offset : " << Offset << "\n"
207  << "<--------->\n");
208 
209  if (!MI.isDebugValue()) {
210  // Make sure Offset fits within the field available.
211  // For MSA instructions, this is a 10-bit signed immediate (scaled by
212  // element size), otherwise it is a 16-bit signed immediate.
213  unsigned OffsetBitSize =
214  getLoadStoreOffsetSizeInBits(MI.getOpcode(), MI.getOperand(OpNo - 1));
215  const Align OffsetAlign(getLoadStoreOffsetAlign(MI.getOpcode()));
216  if (OffsetBitSize < 16 && isInt<16>(Offset) &&
217  (!isIntN(OffsetBitSize, Offset) || !isAligned(OffsetAlign, Offset))) {
218  // If we have an offset that needs to fit into a signed n-bit immediate
219  // (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu
220  MachineBasicBlock &MBB = *MI.getParent();
221  DebugLoc DL = II->getDebugLoc();
222  const TargetRegisterClass *PtrRC =
223  ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
225  Register Reg = RegInfo.createVirtualRegister(PtrRC);
226  const MipsSEInstrInfo &TII =
227  *static_cast<const MipsSEInstrInfo *>(
229  BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAddiuOp()), Reg)
230  .addReg(FrameReg)
231  .addImm(Offset);
232 
233  FrameReg = Reg;
234  Offset = 0;
235  IsKill = true;
236  } else if (!isInt<16>(Offset)) {
237  // Otherwise split the offset into 16-bit pieces and add it in multiple
238  // instructions.
239  MachineBasicBlock &MBB = *MI.getParent();
240  DebugLoc DL = II->getDebugLoc();
241  unsigned NewImm = 0;
242  const MipsSEInstrInfo &TII =
243  *static_cast<const MipsSEInstrInfo *>(
245  unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL,
246  OffsetBitSize == 16 ? &NewImm : nullptr);
247  BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAdduOp()), Reg).addReg(FrameReg)
249 
250  FrameReg = Reg;
251  Offset = SignExtend64<16>(NewImm);
252  IsKill = true;
253  }
254  }
255 
256  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
257  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
258 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::MachineFrameInfo::hasVarSizedObjects
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
Definition: MachineFrameInfo.h:353
ABI
Generic address nodes are lowered to some combination of target independent and machine specific ABI
Definition: Relocation.txt:34
llvm::MipsTargetMachine
Definition: MipsTargetMachine.h:27
llvm::isAligned
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition: Alignment.h:138
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::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::MipsABIInfo
Definition: MipsABIInfo.h:22
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
ErrorHandling.h
llvm::MipsSERegisterInfo::intRegClass
const TargetRegisterClass * intRegClass(unsigned Size) const override
Return GPR register class.
Definition: MipsSERegisterInfo.cpp:54
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
getLoadStoreOffsetAlign
static unsigned getLoadStoreOffsetAlign(const unsigned Opcode)
Get the scale factor applied to the immediate in the given load/store.
Definition: MipsSERegisterInfo.cpp:129
TargetInstrInfo.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
STLExtras.h
MipsTargetMachine.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MipsFunctionInfo
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Definition: MipsMachineFunction.h:25
llvm::MipsSEInstrInfo
Definition: MipsSEInstrInfo.h:21
MachineRegisterInfo.h
llvm::ISD::INLINEASM
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:980
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
TargetMachine.h
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:410
Constants.h
llvm::MipsRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Debug information queries.
Definition: MipsRegisterInfo.cpp:275
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
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
MipsSEInstrInfo.h
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
Mips.h
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineFrameInfo::isFixedObjectIndex
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
Definition: MachineFrameInfo.h:656
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::MachineOperand::getParent
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Definition: MachineOperand.h:238
llvm::isIntN
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:460
Type.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MipsFunctionInfo::isEhDataRegFI
bool isEhDataRegFI(int FI) const
Definition: MipsMachineFunction.cpp:175
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::MipsSubtarget::hasMips32r6
bool hasMips32r6() const
Definition: MipsSubtarget.h:268
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
uint64_t
DebugInfo.h
MipsMachineFunction.h
llvm::MipsRegisterInfo
Definition: MipsRegisterInfo.h:27
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:642
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::InlineAsm::getMemoryConstraintID
static unsigned getMemoryConstraintID(unsigned Flag)
Definition: InlineAsm.h:332
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::MachineFunction
Definition: MachineFunction.h:230
TargetOptions.h
llvm::MachineFrameInfo::getCalleeSavedInfo
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
Definition: MachineFrameInfo.h:755
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:286
llvm::MipsFunctionInfo::isISRRegFI
bool isISRRegFI(int FI) const
Definition: MipsMachineFunction.cpp:180
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MipsSubtarget::inMicroMipsMode
bool inMicroMipsMode() const
Definition: MipsSubtarget.h:311
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::isInt< 16 >
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:370
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:622
MachineFrameInfo.h
MipsSERegisterInfo.h
Function.h
getLoadStoreOffsetSizeInBits
static unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode, MachineOperand MO)
Get the size of the offset supported by the given load/store/inline asm.
Definition: MipsSERegisterInfo.cpp:65
llvm::MipsSERegisterInfo::MipsSERegisterInfo
MipsSERegisterInfo()
Definition: MipsSERegisterInfo.cpp:41
llvm::InlineAsm::Constraint_ZC
@ Constraint_ZC
Definition: InlineAsm.h:264
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
MachineInstrBuilder.h
llvm::MipsSERegisterInfo::requiresFrameIndexScavenging
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
Definition: MipsSERegisterInfo.cpp:49
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
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
MipsSubtarget.h
llvm::MipsSERegisterInfo::requiresRegisterScavenging
bool requiresRegisterScavenging(const MachineFunction &MF) const override
Definition: MipsSERegisterInfo.cpp:44
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
raw_ostream.h
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
Debug.h