LLVM  9.0.0svn
LanaiRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- LanaiRegisterInfo.cpp - Lanai 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 Lanai implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LanaiRegisterInfo.h"
14 #include "Lanai.h"
15 #include "LanaiSubtarget.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/Type.h"
27 
28 #define GET_REGINFO_TARGET_DESC
29 #include "LanaiGenRegisterInfo.inc"
30 
31 using namespace llvm;
32 
34 
35 const uint16_t *
37  return CSR_SaveList;
38 }
39 
41  BitVector Reserved(getNumRegs());
42 
43  Reserved.set(Lanai::R0);
44  Reserved.set(Lanai::R1);
45  Reserved.set(Lanai::PC);
46  Reserved.set(Lanai::R2);
47  Reserved.set(Lanai::SP);
48  Reserved.set(Lanai::R4);
49  Reserved.set(Lanai::FP);
50  Reserved.set(Lanai::R5);
51  Reserved.set(Lanai::RR1);
52  Reserved.set(Lanai::R10);
53  Reserved.set(Lanai::RR2);
54  Reserved.set(Lanai::R11);
55  Reserved.set(Lanai::RCA);
56  Reserved.set(Lanai::R15);
57  if (hasBasePointer(MF))
58  Reserved.set(getBaseRegister());
59  return Reserved;
60 }
61 
63  const MachineFunction & /*MF*/) const {
64  return true;
65 }
66 
68  const MachineFunction & /*MF*/) const {
69  return true;
70 }
71 
72 static bool isALUArithLoOpcode(unsigned Opcode) {
73  switch (Opcode) {
74  case Lanai::ADD_I_LO:
75  case Lanai::SUB_I_LO:
76  case Lanai::ADD_F_I_LO:
77  case Lanai::SUB_F_I_LO:
78  case Lanai::ADDC_I_LO:
79  case Lanai::SUBB_I_LO:
80  case Lanai::ADDC_F_I_LO:
81  case Lanai::SUBB_F_I_LO:
82  return true;
83  default:
84  return false;
85  }
86 }
87 
88 static unsigned getOppositeALULoOpcode(unsigned Opcode) {
89  switch (Opcode) {
90  case Lanai::ADD_I_LO:
91  return Lanai::SUB_I_LO;
92  case Lanai::SUB_I_LO:
93  return Lanai::ADD_I_LO;
94  case Lanai::ADD_F_I_LO:
95  return Lanai::SUB_F_I_LO;
96  case Lanai::SUB_F_I_LO:
97  return Lanai::ADD_F_I_LO;
98  case Lanai::ADDC_I_LO:
99  return Lanai::SUBB_I_LO;
100  case Lanai::SUBB_I_LO:
101  return Lanai::ADDC_I_LO;
102  case Lanai::ADDC_F_I_LO:
103  return Lanai::SUBB_F_I_LO;
104  case Lanai::SUBB_F_I_LO:
105  return Lanai::ADDC_F_I_LO;
106  default:
107  llvm_unreachable("Invalid ALU lo opcode");
108  }
109 }
110 
111 static unsigned getRRMOpcodeVariant(unsigned Opcode) {
112  switch (Opcode) {
113  case Lanai::LDBs_RI:
114  return Lanai::LDBs_RR;
115  case Lanai::LDBz_RI:
116  return Lanai::LDBz_RR;
117  case Lanai::LDHs_RI:
118  return Lanai::LDHs_RR;
119  case Lanai::LDHz_RI:
120  return Lanai::LDHz_RR;
121  case Lanai::LDW_RI:
122  return Lanai::LDW_RR;
123  case Lanai::STB_RI:
124  return Lanai::STB_RR;
125  case Lanai::STH_RI:
126  return Lanai::STH_RR;
127  case Lanai::SW_RI:
128  return Lanai::SW_RR;
129  default:
130  llvm_unreachable("Opcode has no RRM variant");
131  }
132 }
133 
135  int SPAdj, unsigned FIOperandNum,
136  RegScavenger *RS) const {
137  assert(SPAdj == 0 && "Unexpected");
138 
139  MachineInstr &MI = *II;
140  MachineFunction &MF = *MI.getParent()->getParent();
143  bool HasFP = TFI->hasFP(MF);
144  DebugLoc DL = MI.getDebugLoc();
145 
146  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
147 
148  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
149  MI.getOperand(FIOperandNum + 1).getImm();
150 
151  // Addressable stack objects are addressed using neg. offsets from fp
152  // or pos. offsets from sp/basepointer
153  if (!HasFP || (needsStackRealignment(MF) && FrameIndex >= 0))
154  Offset += MF.getFrameInfo().getStackSize();
155 
156  unsigned FrameReg = getFrameRegister(MF);
157  if (FrameIndex >= 0) {
158  if (hasBasePointer(MF))
159  FrameReg = getBaseRegister();
160  else if (needsStackRealignment(MF))
161  FrameReg = Lanai::SP;
162  }
163 
164  // Replace frame index with a frame pointer reference.
165  // If the offset is small enough to fit in the immediate field, directly
166  // encode it.
167  // Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.
168  if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) ||
169  !isInt<16>(Offset)) {
170  assert(RS && "Register scavenging must be on");
171  unsigned Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);
172  if (!Reg)
173  Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj);
174  assert(Reg && "Register scavenger failed");
175 
176  bool HasNegOffset = false;
177  // ALU ops have unsigned immediate values. If the Offset is negative, we
178  // negate it here and reverse the opcode later.
179  if (Offset < 0) {
180  HasNegOffset = true;
181  Offset = -Offset;
182  }
183 
184  if (!isInt<16>(Offset)) {
185  // Reg = hi(offset) | lo(offset)
186  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)
187  .addImm(static_cast<uint32_t>(Offset) >> 16);
188  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)
189  .addReg(Reg)
190  .addImm(Offset & 0xffffU);
191  } else {
192  // Reg = mov(offset)
193  BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
194  .addImm(0)
195  .addImm(Offset);
196  }
197  // Reg = FrameReg OP Reg
198  if (MI.getOpcode() == Lanai::ADD_I_LO) {
199  BuildMI(*MI.getParent(), II, DL,
200  HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
201  MI.getOperand(0).getReg())
202  .addReg(FrameReg)
203  .addReg(Reg)
205  MI.eraseFromParent();
206  return;
207  }
208  if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
209  MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
210  if (HasNegOffset) {
211  // Change the ALU op (operand 3) from LPAC::ADD (the default) to
212  // LPAC::SUB with the already negated offset.
213  assert((MI.getOperand(3).getImm() == LPAC::ADD) &&
214  "Unexpected ALU op in RRM instruction");
215  MI.getOperand(3).setImm(LPAC::SUB);
216  }
217  } else
218  llvm_unreachable("Unexpected opcode in frame index operation");
219 
220  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
221  MI.getOperand(FIOperandNum + 1)
222  .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
223  /*isKill=*/true);
224  return;
225  }
226 
227  // ALU arithmetic ops take unsigned immediates. If the offset is negative,
228  // we replace the instruction with one that inverts the opcode and negates
229  // the immediate.
230  if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) {
231  unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());
232  // We know this is an ALU op, so we know the operands are as follows:
233  // 0: destination register
234  // 1: source register (frame register)
235  // 2: immediate
236  BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
237  MI.getOperand(0).getReg())
238  .addReg(FrameReg)
239  .addImm(-Offset);
240  MI.eraseFromParent();
241  } else {
242  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
243  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
244  }
245 }
246 
248  const MachineFrameInfo &MFI = MF.getFrameInfo();
249  // When we need stack realignment and there are dynamic allocas, we can't
250  // reference off of the stack pointer, so we reserve a base pointer.
251  if (needsStackRealignment(MF) && MFI.hasVarSizedObjects())
252  return true;
253 
254  return false;
255 }
256 
257 unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
258 
259 unsigned
261  return Lanai::FP;
262 }
263 
264 unsigned LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
265 
266 const uint32_t *
268  CallingConv::ID /*CC*/) const {
269  return CSR_RegMask;
270 }
BitVector & set()
Definition: BitVector.h:397
#define R4(n)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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:382
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:305
A debug info location.
Definition: DebugLoc.h:33
#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:408
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:253
Representation of each machine instruction.
Definition: MachineInstr.h:63
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:44
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:413
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