LLVM  8.0.1
LanaiRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//
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 Lanai implementation of the TargetRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "LanaiRegisterInfo.h"
15 #include "Lanai.h"
16 #include "LanaiSubtarget.h"
17 #include "llvm/ADT/BitVector.h"
18 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/Type.h"
28 
29 #define GET_REGINFO_TARGET_DESC
30 #include "LanaiGenRegisterInfo.inc"
31 
32 using namespace llvm;
33 
35 
36 const uint16_t *
38  return CSR_SaveList;
39 }
40 
42  BitVector Reserved(getNumRegs());
43 
44  Reserved.set(Lanai::R0);
45  Reserved.set(Lanai::R1);
46  Reserved.set(Lanai::PC);
47  Reserved.set(Lanai::R2);
48  Reserved.set(Lanai::SP);
49  Reserved.set(Lanai::R4);
50  Reserved.set(Lanai::FP);
51  Reserved.set(Lanai::R5);
52  Reserved.set(Lanai::RR1);
53  Reserved.set(Lanai::R10);
54  Reserved.set(Lanai::RR2);
55  Reserved.set(Lanai::R11);
56  Reserved.set(Lanai::RCA);
57  Reserved.set(Lanai::R15);
58  if (hasBasePointer(MF))
59  Reserved.set(getBaseRegister());
60  return Reserved;
61 }
62 
64  const MachineFunction & /*MF*/) const {
65  return true;
66 }
67 
69  const MachineFunction & /*MF*/) const {
70  return true;
71 }
72 
73 static bool isALUArithLoOpcode(unsigned Opcode) {
74  switch (Opcode) {
75  case Lanai::ADD_I_LO:
76  case Lanai::SUB_I_LO:
77  case Lanai::ADD_F_I_LO:
78  case Lanai::SUB_F_I_LO:
79  case Lanai::ADDC_I_LO:
80  case Lanai::SUBB_I_LO:
81  case Lanai::ADDC_F_I_LO:
82  case Lanai::SUBB_F_I_LO:
83  return true;
84  default:
85  return false;
86  }
87 }
88 
89 static unsigned getOppositeALULoOpcode(unsigned Opcode) {
90  switch (Opcode) {
91  case Lanai::ADD_I_LO:
92  return Lanai::SUB_I_LO;
93  case Lanai::SUB_I_LO:
94  return Lanai::ADD_I_LO;
95  case Lanai::ADD_F_I_LO:
96  return Lanai::SUB_F_I_LO;
97  case Lanai::SUB_F_I_LO:
98  return Lanai::ADD_F_I_LO;
99  case Lanai::ADDC_I_LO:
100  return Lanai::SUBB_I_LO;
101  case Lanai::SUBB_I_LO:
102  return Lanai::ADDC_I_LO;
103  case Lanai::ADDC_F_I_LO:
104  return Lanai::SUBB_F_I_LO;
105  case Lanai::SUBB_F_I_LO:
106  return Lanai::ADDC_F_I_LO;
107  default:
108  llvm_unreachable("Invalid ALU lo opcode");
109  }
110 }
111 
112 static unsigned getRRMOpcodeVariant(unsigned Opcode) {
113  switch (Opcode) {
114  case Lanai::LDBs_RI:
115  return Lanai::LDBs_RR;
116  case Lanai::LDBz_RI:
117  return Lanai::LDBz_RR;
118  case Lanai::LDHs_RI:
119  return Lanai::LDHs_RR;
120  case Lanai::LDHz_RI:
121  return Lanai::LDHz_RR;
122  case Lanai::LDW_RI:
123  return Lanai::LDW_RR;
124  case Lanai::STB_RI:
125  return Lanai::STB_RR;
126  case Lanai::STH_RI:
127  return Lanai::STH_RR;
128  case Lanai::SW_RI:
129  return Lanai::SW_RR;
130  default:
131  llvm_unreachable("Opcode has no RRM variant");
132  }
133 }
134 
136  int SPAdj, unsigned FIOperandNum,
137  RegScavenger *RS) const {
138  assert(SPAdj == 0 && "Unexpected");
139 
140  MachineInstr &MI = *II;
141  MachineFunction &MF = *MI.getParent()->getParent();
144  bool HasFP = TFI->hasFP(MF);
145  DebugLoc DL = MI.getDebugLoc();
146 
147  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
148 
149  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
150  MI.getOperand(FIOperandNum + 1).getImm();
151 
152  // Addressable stack objects are addressed using neg. offsets from fp
153  // or pos. offsets from sp/basepointer
154  if (!HasFP || (needsStackRealignment(MF) && FrameIndex >= 0))
155  Offset += MF.getFrameInfo().getStackSize();
156 
157  unsigned FrameReg = getFrameRegister(MF);
158  if (FrameIndex >= 0) {
159  if (hasBasePointer(MF))
160  FrameReg = getBaseRegister();
161  else if (needsStackRealignment(MF))
162  FrameReg = Lanai::SP;
163  }
164 
165  // Replace frame index with a frame pointer reference.
166  // If the offset is small enough to fit in the immediate field, directly
167  // encode it.
168  // Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.
169  if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) ||
170  !isInt<16>(Offset)) {
171  assert(RS && "Register scavenging must be on");
172  unsigned Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);
173  if (!Reg)
174  Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj);
175  assert(Reg && "Register scavenger failed");
176 
177  bool HasNegOffset = false;
178  // ALU ops have unsigned immediate values. If the Offset is negative, we
179  // negate it here and reverse the opcode later.
180  if (Offset < 0) {
181  HasNegOffset = true;
182  Offset = -Offset;
183  }
184 
185  if (!isInt<16>(Offset)) {
186  // Reg = hi(offset) | lo(offset)
187  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)
188  .addImm(static_cast<uint32_t>(Offset) >> 16);
189  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)
190  .addReg(Reg)
191  .addImm(Offset & 0xffffU);
192  } else {
193  // Reg = mov(offset)
194  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
195  .addImm(0)
196  .addImm(Offset);
197  }
198  // Reg = FrameReg OP Reg
199  if (MI.getOpcode() == Lanai::ADD_I_LO) {
200  BuildMI(*MI.getParent(), II, DL,
201  HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
202  MI.getOperand(0).getReg())
203  .addReg(FrameReg)
204  .addReg(Reg)
206  MI.eraseFromParent();
207  return;
208  }
209  if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
210  MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
211  if (HasNegOffset) {
212  // Change the ALU op (operand 3) from LPAC::ADD (the default) to
213  // LPAC::SUB with the already negated offset.
214  assert((MI.getOperand(3).getImm() == LPAC::ADD) &&
215  "Unexpected ALU op in RRM instruction");
216  MI.getOperand(3).setImm(LPAC::SUB);
217  }
218  } else
219  llvm_unreachable("Unexpected opcode in frame index operation");
220 
221  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
222  MI.getOperand(FIOperandNum + 1)
223  .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
224  /*isKill=*/true);
225  return;
226  }
227 
228  // ALU arithmetic ops take unsigned immediates. If the offset is negative,
229  // we replace the instruction with one that inverts the opcode and negates
230  // the immediate.
231  if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) {
232  unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());
233  // We know this is an ALU op, so we know the operands are as follows:
234  // 0: destination register
235  // 1: source register (frame register)
236  // 2: immediate
237  BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
238  MI.getOperand(0).getReg())
239  .addReg(FrameReg)
240  .addImm(-Offset);
241  MI.eraseFromParent();
242  } else {
243  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
244  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
245  }
246 }
247 
249  const MachineFrameInfo &MFI = MF.getFrameInfo();
250  // When we need stack realignment and there are dynamic allocas, we can't
251  // reference off of the stack pointer, so we reserve a base pointer.
252  if (needsStackRealignment(MF) && MFI.hasVarSizedObjects())
253  return true;
254 
255  return false;
256 }
257 
258 unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
259 
260 unsigned
262  return Lanai::FP;
263 }
264 
265 unsigned LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
266 
267 const uint32_t *
269  CallingConv::ID /*CC*/) const {
270  return CSR_RegMask;
271 }
BitVector & set()
Definition: BitVector.h:398
#define R4(n)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static unsigned getOppositeALULoOpcode(unsigned Opcode)
static bool isALUArithLoOpcode(unsigned Opcode)
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...
static unsigned getRRMOpcodeVariant(unsigned Opcode)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
unsigned getReg() const
getReg - Returns the register number.
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
unsigned Reg
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=nullptr) const override
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:306
A debug info location.
Definition: DebugLoc.h:34
#define R2(n)
bool hasBasePointer(const MachineFunction &MF) const
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
unsigned getFrameRegister(const MachineFunction &MF) const override
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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
unsigned FindUnusedReg(const TargetRegisterClass *RC) const
Find an unused register of the specified register class.
virtual const TargetInstrInfo * getInstrInfo() const
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This file declares the machine register scavenger class.
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.
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
void setImm(int64_t immVal)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getBaseRegister() const
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
Information about stack frame layout on the target.
BitVector getReservedRegs(const MachineFunction &MF) const override
int64_t getImm() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static bool isRMOpcode(unsigned Opcode)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getRARegister() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
virtual const TargetFrameLowering * getFrameLowering() const
unsigned scavengeRegister(const TargetRegisterClass *RC, MachineBasicBlock::iterator I, int SPAdj)
Make a register of the specific register class available and do the appropriate bookkeeping.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSPLSOpcode(unsigned Opcode)
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
bool requiresRegisterScavenging(const MachineFunction &MF) const override