LLVM  10.0.0svn
HexagonRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- HexagonRegisterInfo.cpp - Hexagon 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 Hexagon implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "HexagonRegisterInfo.h"
15 #include "Hexagon.h"
17 #include "HexagonSubtarget.h"
18 #include "HexagonTargetMachine.h"
19 #include "llvm/ADT/BitVector.h"
20 #include "llvm/ADT/STLExtras.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Type.h"
33 #include "llvm/Support/Debug.h"
38 
39 #define GET_REGINFO_TARGET_DESC
40 #include "HexagonGenRegisterInfo.inc"
41 
42 using namespace llvm;
43 
45  : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/,
46  0/*PC*/, HwMode) {}
47 
48 
50  return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
51  R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
52 }
53 
54 const MCPhysReg *
56  const TargetRegisterClass *RC) const {
57  using namespace Hexagon;
58 
59  static const MCPhysReg Int32[] = {
60  R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
61  };
62  static const MCPhysReg Int64[] = {
63  D0, D1, D2, D3, D4, D5, D6, D7, 0
64  };
65  static const MCPhysReg Pred[] = {
66  P0, P1, P2, P3, 0
67  };
68  static const MCPhysReg VecSgl[] = {
69  V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13,
70  V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
71  V28, V29, V30, V31, 0
72  };
73  static const MCPhysReg VecDbl[] = {
74  W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
75  };
76 
77  switch (RC->getID()) {
78  case IntRegsRegClassID:
79  return Int32;
80  case DoubleRegsRegClassID:
81  return Int64;
82  case PredRegsRegClassID:
83  return Pred;
84  case HvxVRRegClassID:
85  return VecSgl;
86  case HvxWRRegClassID:
87  return VecDbl;
88  default:
89  break;
90  }
91 
92  static const MCPhysReg Empty[] = { 0 };
93 #ifndef NDEBUG
94  dbgs() << "Register class: " << getRegClassName(RC) << "\n";
95 #endif
96  llvm_unreachable("Unexpected register class");
97  return Empty;
98 }
99 
100 
101 const MCPhysReg *
103  static const MCPhysReg CalleeSavedRegsV3[] = {
104  Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
105  Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
106  Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
107  };
108 
109  // Functions that contain a call to __builtin_eh_return also save the first 4
110  // parameter registers.
111  static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
112  Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
113  Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
114  Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
115  Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
116  };
117 
118  bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn();
119 
120  return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
121 }
122 
123 
125  const MachineFunction &MF, CallingConv::ID) const {
126  return HexagonCSR_RegMask;
127 }
128 
129 
131  const {
132  BitVector Reserved(getNumRegs());
133  Reserved.set(Hexagon::R29);
134  Reserved.set(Hexagon::R30);
135  Reserved.set(Hexagon::R31);
136  Reserved.set(Hexagon::VTMP);
137 
138  // Guest registers.
139  Reserved.set(Hexagon::GELR); // G0
140  Reserved.set(Hexagon::GSR); // G1
141  Reserved.set(Hexagon::GOSP); // G2
142  Reserved.set(Hexagon::G3); // G3
143 
144  // Control registers.
145  Reserved.set(Hexagon::SA0); // C0
146  Reserved.set(Hexagon::LC0); // C1
147  Reserved.set(Hexagon::SA1); // C2
148  Reserved.set(Hexagon::LC1); // C3
149  Reserved.set(Hexagon::P3_0); // C4
150  Reserved.set(Hexagon::USR); // C8
151  Reserved.set(Hexagon::PC); // C9
152  Reserved.set(Hexagon::UGP); // C10
153  Reserved.set(Hexagon::GP); // C11
154  Reserved.set(Hexagon::CS0); // C12
155  Reserved.set(Hexagon::CS1); // C13
156  Reserved.set(Hexagon::UPCYCLELO); // C14
157  Reserved.set(Hexagon::UPCYCLEHI); // C15
158  Reserved.set(Hexagon::FRAMELIMIT); // C16
159  Reserved.set(Hexagon::FRAMEKEY); // C17
160  Reserved.set(Hexagon::PKTCOUNTLO); // C18
161  Reserved.set(Hexagon::PKTCOUNTHI); // C19
162  Reserved.set(Hexagon::UTIMERLO); // C30
163  Reserved.set(Hexagon::UTIMERHI); // C31
164  // Out of the control registers, only C8 is explicitly defined in
165  // HexagonRegisterInfo.td. If others are defined, make sure to add
166  // them here as well.
167  Reserved.set(Hexagon::C8);
168  Reserved.set(Hexagon::USR_OVF);
169 
171  Reserved.set(Hexagon::R19);
172 
173  for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x))
174  markSuperRegs(Reserved, x);
175 
176  return Reserved;
177 }
178 
179 
181  int SPAdj, unsigned FIOp,
182  RegScavenger *RS) const {
183  //
184  // Hexagon_TODO: Do we need to enforce this for Hexagon?
185  assert(SPAdj == 0 && "Unexpected");
186 
187  MachineInstr &MI = *II;
188  MachineBasicBlock &MB = *MI.getParent();
189  MachineFunction &MF = *MB.getParent();
190  auto &HST = MF.getSubtarget<HexagonSubtarget>();
191  auto &HII = *HST.getInstrInfo();
192  auto &HFI = *HST.getFrameLowering();
193 
194  unsigned BP = 0;
195  int FI = MI.getOperand(FIOp).getIndex();
196  // Select the base pointer (BP) and calculate the actual offset from BP
197  // to the beginning of the object at index FI.
198  int Offset = HFI.getFrameIndexReference(MF, FI, BP);
199  // Add the offset from the instruction.
200  int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
201  bool IsKill = false;
202 
203  unsigned Opc = MI.getOpcode();
204  switch (Opc) {
205  case Hexagon::PS_fia:
206  MI.setDesc(HII.get(Hexagon::A2_addi));
207  MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
208  MI.RemoveOperand(FIOp+1);
209  return;
210  case Hexagon::PS_fi:
211  // Set up the instruction for updating below.
212  MI.setDesc(HII.get(Hexagon::A2_addi));
213  break;
214  }
215 
216  if (!HII.isValidOffset(Opc, RealOffset, this)) {
217  // If the offset is not valid, calculate the address in a temporary
218  // register and use it with offset 0.
219  auto &MRI = MF.getRegInfo();
220  Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
221  const DebugLoc &DL = MI.getDebugLoc();
222  BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR)
223  .addReg(BP)
224  .addImm(RealOffset);
225  BP = TmpR;
226  RealOffset = 0;
227  IsKill = true;
228  }
229 
230  MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill);
231  MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
232 }
233 
234 
236  const TargetRegisterClass *SrcRC, unsigned SubReg,
237  const TargetRegisterClass *DstRC, unsigned DstSubReg,
238  const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
239  // Coalescing will extend the live interval of the destination register.
240  // If the destination register is a vector pair, avoid introducing function
241  // calls into the interval, since it could result in a spilling of a pair
242  // instead of a single vector.
243  MachineFunction &MF = *MI->getParent()->getParent();
245  if (!HST.useHVXOps() || NewRC->getID() != Hexagon::HvxWRRegClass.getID())
246  return true;
247  bool SmallSrc = SrcRC->getID() == Hexagon::HvxVRRegClass.getID();
248  bool SmallDst = DstRC->getID() == Hexagon::HvxVRRegClass.getID();
249  if (!SmallSrc && !SmallDst)
250  return true;
251 
252  Register DstReg = MI->getOperand(0).getReg();
253  Register SrcReg = MI->getOperand(1).getReg();
254  const SlotIndexes &Indexes = *LIS.getSlotIndexes();
255  auto HasCall = [&Indexes] (const LiveInterval::Segment &S) {
256  for (SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
257  I != E; I = I.getNextIndex()) {
258  if (const MachineInstr *MI = Indexes.getInstructionFromIndex(I))
259  if (MI->isCall())
260  return true;
261  }
262  return false;
263  };
264 
265  if (SmallSrc == SmallDst) {
266  // Both must be true, because the case for both being false was
267  // checked earlier. Both registers will be coalesced into a register
268  // of a wider class (HvxWR), and we don't want its live range to
269  // span over calls.
270  return !any_of(LIS.getInterval(DstReg), HasCall) &&
271  !any_of(LIS.getInterval(SrcReg), HasCall);
272  }
273 
274  // If one register is large (HvxWR) and the other is small (HvxVR), then
275  // coalescing is ok if the large is already live across a function call,
276  // or if the small one is not.
277  unsigned SmallReg = SmallSrc ? SrcReg : DstReg;
278  unsigned LargeReg = SmallSrc ? DstReg : SrcReg;
279  return any_of(LIS.getInterval(LargeReg), HasCall) ||
280  !any_of(LIS.getInterval(SmallReg), HasCall);
281 }
282 
283 
285  return Hexagon::R31;
286 }
287 
288 
290  &MF) const {
291  const HexagonFrameLowering *TFI = getFrameLowering(MF);
292  if (TFI->hasFP(MF))
293  return getFrameRegister();
294  return getStackRegister();
295 }
296 
297 
299  return Hexagon::R30;
300 }
301 
302 
304  return Hexagon::R29;
305 }
306 
307 
309  const TargetRegisterClass &RC, unsigned GenIdx) const {
310  assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi);
311 
312  static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
313  static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
314  static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
315 
316  switch (RC.getID()) {
317  case Hexagon::CtrRegs64RegClassID:
318  case Hexagon::DoubleRegsRegClassID:
319  return ISub[GenIdx];
320  case Hexagon::HvxWRRegClassID:
321  return VSub[GenIdx];
322  case Hexagon::HvxVQRRegClassID:
323  return WSub[GenIdx];
324  }
325 
326  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
327  return getHexagonSubRegIndex(*SuperRC, GenIdx);
328 
329  llvm_unreachable("Invalid register class");
330 }
331 
333  const {
334  return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
335 }
336 
337 const TargetRegisterClass *
339  unsigned Kind) const {
340  return &Hexagon::IntRegsRegClass;
341 }
342 
344  return Hexagon::R6;
345 }
346 
BitVector & set()
Definition: BitVector.h:397
#define R4(n)
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:657
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
Hexagon target-specific information for each MachineFunction.
This represents a simple continuous liveness interval for a value.
Definition: LiveInterval.h:161
A debug info location.
Definition: DebugLoc.h:33
#define R2(n)
bool isEHReturnCalleeSaveReg(unsigned Reg) const
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
Definition: BitVector.h:331
unsigned SubReg
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Definition: BitVector.h:339
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
unsigned getID() const
Return the register class ID number.
SlotIndexes pass.
Definition: SlotIndexes.h:314
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
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.
sc_iterator getSuperClasses() const
Returns a NULL-terminated list of super-classes.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
Definition: SlotIndexes.h:406
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1172
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
LiveInterval & getInterval(Register Reg)
HexagonRegisterInfo(unsigned HwMode)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
#define R6(n)
unsigned getFirstCallerSavedNonParamReg() const
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
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.
bool useFPForScavengingIndex(const MachineFunction &MF) const override
Returns true if the frame pointer is valid.
#define I(x, y, z)
Definition: MD5.cpp:58
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...
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
SlotIndexes * getSlotIndexes() const
BitVector getReservedRegs(const MachineFunction &MF) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const HexagonInstrInfo * getInstrInfo() const override
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
IRTranslator LLVM IR MI
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:83
unsigned getHexagonSubRegIndex(const TargetRegisterClass &RC, unsigned GenIdx) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19