LLVM  10.0.0svn
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->needsStackRealignment(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 =
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;
224  MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
225  Register Reg = RegInfo.createVirtualRegister(PtrRC);
226  const MipsSEInstrInfo &TII =
227  *static_cast<const MipsSEInstrInfo *>(
228  MBB.getParent()->getSubtarget().getInstrInfo());
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 *>(
244  MBB.getParent()->getSubtarget().getInstrInfo());
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)
248  .addReg(Reg, RegState::Kill);
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 }
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned Reg
Register getFrameRegister(const MachineFunction &MF) const override
Debug information queries.
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:342
A debug info location.
Definition: DebugLoc.h:33
const HexagonInstrInfo * TII
bool inMicroMipsMode() const
bool hasMips32r6() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:696
virtual const TargetInstrInfo * getInstrInfo() const
bool requiresRegisterScavenging(const MachineFunction &MF) const override
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
static unsigned getMemoryConstraintID(unsigned Flag)
Definition: InlineAsm.h:329
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:434
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
const TargetRegisterClass * intRegClass(unsigned Size) const override
Return GPR register class.
CHAIN = SC CHAIN, Imm128 - System call.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition: Alignment.h:146
int64_t getImm() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
uint32_t Size
Definition: Profile.cpp:46
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
unsigned loadImmediate(int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, unsigned *NewImm) const
Emit a series of instructions to load an immediate.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
bool isEhDataRegFI(int FI) const
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static unsigned getLoadStoreOffsetAlign(const unsigned Opcode)
Get the scale factor applied to the immediate in the given load/store.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool isISRRegFI(int FI) const
static unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode, MachineOperand MO)
Get the size of the offset supported by the given load/store/inline asm.
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override