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