LLVM  8.0.1
MipsSERegisterInfo.cpp
Go to the documentation of this file.
1 //===-- MipsSERegisterInfo.cpp - MIPS32/64 Register Information -== -------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the MIPS32/64 implementation of the TargetRegisterInfo
11 // class.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "MipsSERegisterInfo.h"
16 #include "Mips.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsSEInstrInfo.h"
19 #include "MipsSubtarget.h"
20 #include "MipsTargetMachine.h"
21 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DebugInfo.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/Support/Debug.h"
37 
38 using namespace llvm;
39 
40 #define DEBUG_TYPE "mips-reg-info"
41 
43 
46  return true;
47 }
48 
51  return true;
52 }
53 
54 const TargetRegisterClass *
56  if (Size == 4)
57  return &Mips::GPR32RegClass;
58 
59  assert(Size == 8);
60  return &Mips::GPR64RegClass;
61 }
62 
63 /// Get the size of the offset supported by the given load/store/inline asm.
64 /// The result includes the effects of any scale factors applied to the
65 /// instruction immediate.
66 static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode,
67  MachineOperand MO) {
68  switch (Opcode) {
69  case Mips::LD_B:
70  case Mips::ST_B:
71  return 10;
72  case Mips::LD_H:
73  case Mips::ST_H:
74  return 10 + 1 /* scale factor */;
75  case Mips::LD_W:
76  case Mips::ST_W:
77  return 10 + 2 /* scale factor */;
78  case Mips::LD_D:
79  case Mips::ST_D:
80  return 10 + 3 /* scale factor */;
81  case Mips::LL:
82  case Mips::LL64:
83  case Mips::LLD:
84  case Mips::LLE:
85  case Mips::SC:
86  case Mips::SC64:
87  case Mips::SCD:
88  case Mips::SCE:
89  return 16;
90  case Mips::LLE_MM:
91  case Mips::LL_MM:
92  case Mips::SCE_MM:
93  case Mips::SC_MM:
94  return 12;
95  case Mips::LL64_R6:
96  case Mips::LL_R6:
97  case Mips::LLD_R6:
98  case Mips::SC64_R6:
99  case Mips::SCD_R6:
100  case Mips::SC_R6:
101  case Mips::LL_MMR6:
102  case Mips::SC_MMR6:
103  return 9;
104  case Mips::INLINEASM: {
105  unsigned ConstraintID = InlineAsm::getMemoryConstraintID(MO.getImm());
106  switch (ConstraintID) {
108  const MipsSubtarget &Subtarget = MO.getParent()
109  ->getParent()
110  ->getParent()
112  if (Subtarget.inMicroMipsMode())
113  return 12;
114 
115  if (Subtarget.hasMips32r6())
116  return 9;
117 
118  return 16;
119  }
120  default:
121  return 16;
122  }
123  }
124  default:
125  return 16;
126  }
127 }
128 
129 /// Get the scale factor applied to the immediate in the given load/store.
130 static inline unsigned getLoadStoreOffsetAlign(const unsigned Opcode) {
131  switch (Opcode) {
132  case Mips::LD_H:
133  case Mips::ST_H:
134  return 2;
135  case Mips::LD_W:
136  case Mips::ST_W:
137  return 4;
138  case Mips::LD_D:
139  case Mips::ST_D:
140  return 8;
141  default:
142  return 1;
143  }
144 }
145 
146 void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
147  unsigned OpNo, int FrameIndex,
148  uint64_t StackSize,
149  int64_t SPOffset) const {
150  MachineInstr &MI = *II;
151  MachineFunction &MF = *MI.getParent()->getParent();
152  MachineFrameInfo &MFI = MF.getFrameInfo();
153  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
154 
155  MipsABIInfo ABI =
156  static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
157  const MipsRegisterInfo *RegInfo =
158  static_cast<const MipsRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
159 
160  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
161  int MinCSFI = 0;
162  int MaxCSFI = -1;
163 
164  if (CSI.size()) {
165  MinCSFI = CSI[0].getFrameIdx();
166  MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
167  }
168 
169  bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);
170  bool IsISRRegFI = MipsFI->isISRRegFI(FrameIndex);
171  // The following stack frame objects are always referenced relative to $sp:
172  // 1. Outgoing arguments.
173  // 2. Pointer to dynamically allocated stack space.
174  // 3. Locations for callee-saved registers.
175  // 4. Locations for eh data registers.
176  // 5. Locations for ISR saved Coprocessor 0 registers 12 & 14.
177  // Everything else is referenced relative to whatever register
178  // getFrameRegister() returns.
179  unsigned FrameReg;
180 
181  if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI ||
182  IsISRRegFI)
183  FrameReg = ABI.GetStackPtr();
184  else if (RegInfo->needsStackRealignment(MF)) {
186  FrameReg = ABI.GetBasePtr();
187  else if (MFI.isFixedObjectIndex(FrameIndex))
188  FrameReg = getFrameRegister(MF);
189  else
190  FrameReg = ABI.GetStackPtr();
191  } else
192  FrameReg = getFrameRegister(MF);
193 
194  // Calculate final offset.
195  // - There is no need to change the offset if the frame object is one of the
196  // following: an outgoing argument, pointer to a dynamically allocated
197  // stack space or a $gp restore location,
198  // - If the frame object is any of the following, its offset must be adjusted
199  // by adding the size of the stack:
200  // incoming argument, callee-saved register location or local variable.
201  bool IsKill = false;
202  int64_t Offset;
203 
204  Offset = SPOffset + (int64_t)StackSize;
205  Offset += MI.getOperand(OpNo + 1).getImm();
206 
207  LLVM_DEBUG(errs() << "Offset : " << Offset << "\n"
208  << "<--------->\n");
209 
210  if (!MI.isDebugValue()) {
211  // Make sure Offset fits within the field available.
212  // For MSA instructions, this is a 10-bit signed immediate (scaled by
213  // element size), otherwise it is a 16-bit signed immediate.
214  unsigned OffsetBitSize =
216  unsigned OffsetAlign = getLoadStoreOffsetAlign(MI.getOpcode());
217 
218  if (OffsetBitSize < 16 && isInt<16>(Offset) &&
219  (!isIntN(OffsetBitSize, Offset) ||
220  OffsetToAlignment(Offset, OffsetAlign) != 0)) {
221  // If we have an offset that needs to fit into a signed n-bit immediate
222  // (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu
223  MachineBasicBlock &MBB = *MI.getParent();
224  DebugLoc DL = II->getDebugLoc();
225  const TargetRegisterClass *PtrRC =
226  ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
227  MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
228  unsigned Reg = RegInfo.createVirtualRegister(PtrRC);
229  const MipsSEInstrInfo &TII =
230  *static_cast<const MipsSEInstrInfo *>(
231  MBB.getParent()->getSubtarget().getInstrInfo());
232  BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAddiuOp()), Reg)
233  .addReg(FrameReg)
234  .addImm(Offset);
235 
236  FrameReg = Reg;
237  Offset = 0;
238  IsKill = true;
239  } else if (!isInt<16>(Offset)) {
240  // Otherwise split the offset into 16-bit pieces and add it in multiple
241  // instructions.
242  MachineBasicBlock &MBB = *MI.getParent();
243  DebugLoc DL = II->getDebugLoc();
244  unsigned NewImm = 0;
245  const MipsSEInstrInfo &TII =
246  *static_cast<const MipsSEInstrInfo *>(
247  MBB.getParent()->getSubtarget().getInstrInfo());
248  unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL,
249  OffsetBitSize == 16 ? &NewImm : nullptr);
250  BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAdduOp()), Reg).addReg(FrameReg)
251  .addReg(Reg, RegState::Kill);
252 
253  FrameReg = Reg;
254  Offset = SignExtend64<16>(NewImm);
255  IsKill = true;
256  }
257  }
258 
259  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
260  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
261 }
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:24
void ChangeToRegister(unsigned 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...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned Reg
unsigned getFrameRegister(const MachineFunction &MF) const override
Debug information queries.
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:306
A debug info location.
Definition: DebugLoc.h:34
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:409
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:667
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:398
bool isDebugValue() const
Definition: MachineInstr.h:997
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.
int64_t getImm() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
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.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
uint32_t Size
Definition: Profile.cpp:47
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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())
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: MathExtras.h:727
IRTranslator LLVM IR MI
bool isEhDataRegFI(int FI) const
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
static unsigned getLoadStoreOffsetAlign(const unsigned Opcode)
Get the scale factor applied to the immediate in the given load/store.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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