LLVM  8.0.1
AMDGPURegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- AMDGPURegisterBankInfo.cpp -------------------------------*- 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 /// \file
10 /// This file implements the targeting of the RegisterBankInfo class for
11 /// AMDGPU.
12 /// \todo This should be generated by TableGen.
13 //===----------------------------------------------------------------------===//
14 
15 #include "AMDGPURegisterBankInfo.h"
16 #include "AMDGPUInstrInfo.h"
17 #include "SIMachineFunctionInfo.h"
18 #include "SIRegisterInfo.h"
24 #include "llvm/IR/Constants.h"
25 
26 #define GET_TARGET_REGBANK_IMPL
27 #include "AMDGPUGenRegisterBank.inc"
28 
29 // This file will be TableGen'ed at some point.
30 #include "AMDGPUGenRegisterBankInfo.def"
31 
32 using namespace llvm;
33 
36  TRI(static_cast<const SIRegisterInfo*>(&TRI)) {
37 
38  // HACK: Until this is fully tablegen'd.
39  static bool AlreadyInit = false;
40  if (AlreadyInit)
41  return;
42 
43  AlreadyInit = true;
44 
45  const RegisterBank &RBSGPR = getRegBank(AMDGPU::SGPRRegBankID);
46  (void)RBSGPR;
47  assert(&RBSGPR == &AMDGPU::SGPRRegBank);
48 
49  const RegisterBank &RBVGPR = getRegBank(AMDGPU::VGPRRegBankID);
50  (void)RBVGPR;
51  assert(&RBVGPR == &AMDGPU::VGPRRegBank);
52 
53 }
54 
55 static bool isConstant(const MachineOperand &MO, int64_t &C) {
56  const MachineFunction *MF = MO.getParent()->getParent()->getParent();
57  const MachineRegisterInfo &MRI = MF->getRegInfo();
58  const MachineInstr *Def = MRI.getVRegDef(MO.getReg());
59  if (!Def)
60  return false;
61 
62  if (Def->getOpcode() == AMDGPU::G_CONSTANT) {
63  C = Def->getOperand(1).getCImm()->getSExtValue();
64  return true;
65  }
66 
67  if (Def->getOpcode() == AMDGPU::COPY)
68  return isConstant(Def->getOperand(1), C);
69 
70  return false;
71 }
72 
74  const RegisterBank &Src,
75  unsigned Size) const {
76  if (Dst.getID() == AMDGPU::SGPRRegBankID &&
77  Src.getID() == AMDGPU::VGPRRegBankID) {
79  }
80 
81  // SGPRRegBank with size 1 is actually vcc or another 64-bit sgpr written by
82  // the valu.
83  if (Size == 1 && Dst.getID() == AMDGPU::SCCRegBankID &&
84  (Src.getID() == AMDGPU::SGPRRegBankID ||
85  Src.getID() == AMDGPU::VGPRRegBankID ||
86  Src.getID() == AMDGPU::VCCRegBankID))
88 
89  return RegisterBankInfo::copyCost(Dst, Src, Size);
90 }
91 
93  const TargetRegisterClass &RC) const {
94 
95  if (TRI->isSGPRClass(&RC))
96  return getRegBank(AMDGPU::SGPRRegBankID);
97 
98  return getRegBank(AMDGPU::VGPRRegBankID);
99 }
100 
103  const MachineInstr &MI) const {
104 
105  const MachineFunction &MF = *MI.getParent()->getParent();
106  const MachineRegisterInfo &MRI = MF.getRegInfo();
107 
108 
109  InstructionMappings AltMappings;
110  switch (MI.getOpcode()) {
111  case TargetOpcode::G_LOAD: {
112  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
113  // FIXME: Should we be hard coding the size for these mappings?
114  const InstructionMapping &SSMapping = getInstructionMapping(
115  1, 1, getOperandsMapping(
116  {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
117  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
118  2); // Num Operands
119  AltMappings.push_back(&SSMapping);
120 
121  const InstructionMapping &VVMapping = getInstructionMapping(
122  2, 1, getOperandsMapping(
123  {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
124  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
125  2); // Num Operands
126  AltMappings.push_back(&VVMapping);
127 
128  // FIXME: Should this be the pointer-size (64-bits) or the size of the
129  // register that will hold the bufffer resourc (128-bits).
130  const InstructionMapping &VSMapping = getInstructionMapping(
131  3, 1, getOperandsMapping(
132  {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
133  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
134  2); // Num Operands
135  AltMappings.push_back(&VSMapping);
136 
137  return AltMappings;
138 
139  }
140  case TargetOpcode::G_ICMP: {
141  unsigned Size = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
142  const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
143  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
144  nullptr, // Predicate operand.
145  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
146  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
147  4); // Num Operands
148  AltMappings.push_back(&SSMapping);
149 
150  const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
151  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1),
152  nullptr, // Predicate operand.
153  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
154  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
155  4); // Num Operands
156  AltMappings.push_back(&SVMapping);
157 
158  const InstructionMapping &VSMapping = getInstructionMapping(3, 1,
159  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1),
160  nullptr, // Predicate operand.
161  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
162  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
163  4); // Num Operands
164  AltMappings.push_back(&VSMapping);
165 
166  const InstructionMapping &VVMapping = getInstructionMapping(4, 1,
167  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1),
168  nullptr, // Predicate operand.
169  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
170  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
171  4); // Num Operands
172  AltMappings.push_back(&VVMapping);
173 
174  return AltMappings;
175  }
176  case TargetOpcode::G_SELECT: {
177  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
178  const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
179  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
180  AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
181  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
182  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
183  4); // Num Operands
184  AltMappings.push_back(&SSMapping);
185 
186  const InstructionMapping &VVMapping = getInstructionMapping(2, 1,
187  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
188  AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1),
189  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
190  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
191  4); // Num Operands
192  AltMappings.push_back(&VVMapping);
193 
194  return AltMappings;
195  }
196  case TargetOpcode::G_UADDE:
197  case TargetOpcode::G_USUBE:
198  case TargetOpcode::G_SADDE:
199  case TargetOpcode::G_SSUBE: {
200  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
201  const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
203  {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
204  AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
205  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
206  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
207  AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1)}),
208  5); // Num Operands
209  AltMappings.push_back(&SSMapping);
210 
211  const InstructionMapping &VVMapping = getInstructionMapping(2, 1,
212  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
213  AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1),
214  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
215  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
216  AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1)}),
217  5); // Num Operands
218  AltMappings.push_back(&VVMapping);
219  return AltMappings;
220  }
221  case AMDGPU::G_BRCOND: {
222  assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1);
223 
224  const InstructionMapping &SMapping = getInstructionMapping(
225  1, 1, getOperandsMapping(
226  {AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1), nullptr}),
227  2); // Num Operands
228  AltMappings.push_back(&SMapping);
229 
230  const InstructionMapping &VMapping = getInstructionMapping(
231  1, 1, getOperandsMapping(
232  {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), nullptr }),
233  2); // Num Operands
234  AltMappings.push_back(&VMapping);
235  return AltMappings;
236  }
237  default:
238  break;
239  }
241 }
242 
243 void AMDGPURegisterBankInfo::applyMappingImpl(
244  const OperandsMapper &OpdMapper) const {
245  return applyDefaultMapping(OpdMapper);
246 }
247 
248 static bool isInstrUniform(const MachineInstr &MI) {
249  if (!MI.hasOneMemOperand())
250  return false;
251 
252  const MachineMemOperand *MMO = *MI.memoperands_begin();
253  return AMDGPUInstrInfo::isUniformMMO(MMO);
254 }
255 
256 bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const {
257  const MachineFunction &MF = *MI.getParent()->getParent();
258  const MachineRegisterInfo &MRI = MF.getRegInfo();
259  for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) {
260  if (!MI.getOperand(i).isReg())
261  continue;
262  unsigned Reg = MI.getOperand(i).getReg();
263  if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) {
264  if (Bank->getID() == AMDGPU::VGPRRegBankID)
265  return false;
266 
267  assert(Bank->getID() == AMDGPU::SGPRRegBankID ||
268  Bank->getID() == AMDGPU::SCCRegBankID);
269  }
270  }
271  return true;
272 }
273 
275 AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const {
276  const MachineFunction &MF = *MI.getParent()->getParent();
277  const MachineRegisterInfo &MRI = MF.getRegInfo();
279 
280  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
281  unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
282  unsigned BankID = Size == 1 ? AMDGPU::SCCRegBankID : AMDGPU::SGPRRegBankID;
283  OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size);
284  }
285  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
286  MI.getNumOperands());
287 }
288 
290 AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const {
291  const MachineFunction &MF = *MI.getParent()->getParent();
292  const MachineRegisterInfo &MRI = MF.getRegInfo();
294  unsigned OpdIdx = 0;
295 
296  unsigned Size0 = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
297  OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size0);
298 
299  if (MI.getOperand(OpdIdx).isIntrinsicID())
300  OpdsMapping[OpdIdx++] = nullptr;
301 
302  unsigned Reg1 = MI.getOperand(OpdIdx).getReg();
303  unsigned Size1 = getSizeInBits(Reg1, MRI, *TRI);
304 
305  unsigned DefaultBankID = Size1 == 1 ?
306  AMDGPU::VCCRegBankID : AMDGPU::VGPRRegBankID;
307  unsigned Bank1 = getRegBankID(Reg1, MRI, *TRI, DefaultBankID);
308 
309  OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(Bank1, Size1);
310 
311  for (unsigned e = MI.getNumOperands(); OpdIdx != e; ++OpdIdx) {
312  unsigned Size = getSizeInBits(MI.getOperand(OpdIdx).getReg(), MRI, *TRI);
313  unsigned BankID = Size == 1 ? AMDGPU::VCCRegBankID : AMDGPU::VGPRRegBankID;
314  OpdsMapping[OpdIdx] = AMDGPU::getValueMapping(BankID, Size);
315  }
316 
317  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
318  MI.getNumOperands());
319 }
320 
322 AMDGPURegisterBankInfo::getDefaultMappingAllVGPR(const MachineInstr &MI) const {
323  const MachineFunction &MF = *MI.getParent()->getParent();
324  const MachineRegisterInfo &MRI = MF.getRegInfo();
326 
327  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
328  unsigned Size = getSizeInBits(MI.getOperand(I).getReg(), MRI, *TRI);
329  OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
330  }
331 
332  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
333  MI.getNumOperands());
334 }
335 
337 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
338 
339  const MachineFunction &MF = *MI.getParent()->getParent();
340  const MachineRegisterInfo &MRI = MF.getRegInfo();
342  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
343  unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
344 
345  const ValueMapping *ValMapping;
346  const ValueMapping *PtrMapping;
347 
348  if (isInstrUniform(MI)) {
349  // We have a uniform instruction so we want to use an SMRD load
350  ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
351  PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
352  } else {
353  ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
354  // FIXME: What would happen if we used SGPRRegBankID here?
355  PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
356  }
357 
358  OpdsMapping[0] = ValMapping;
359  OpdsMapping[1] = PtrMapping;
361  1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
362  return Mapping;
363 
364  // FIXME: Do we want to add a mapping for FLAT load, or should we just
365  // handle that during instruction selection?
366 }
367 
368 unsigned
369 AMDGPURegisterBankInfo::getRegBankID(unsigned Reg,
370  const MachineRegisterInfo &MRI,
371  const TargetRegisterInfo &TRI,
372  unsigned Default) const {
373 
374  const RegisterBank *Bank = getRegBank(Reg, MRI, TRI);
375  return Bank ? Bank->getID() : Default;
376 }
377 
378 ///
379 /// This function must return a legal mapping, because
380 /// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called
381 /// in RegBankSelect::Mode::Fast. Any mapping that would cause a
382 /// VGPR to SGPR generated is illegal.
383 ///
387 
388  if (Mapping.isValid())
389  return Mapping;
390 
391  const MachineFunction &MF = *MI.getParent()->getParent();
392  const MachineRegisterInfo &MRI = MF.getRegInfo();
394 
395  switch (MI.getOpcode()) {
396  default:
398 
399  case AMDGPU::G_AND:
400  case AMDGPU::G_OR:
401  case AMDGPU::G_XOR: {
402  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
403  if (Size == 1) {
404  OpdsMapping[0] = OpdsMapping[1] =
405  OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
406  break;
407  }
408 
410  }
411 
412  case AMDGPU::G_ADD:
413  case AMDGPU::G_SUB:
414  case AMDGPU::G_MUL:
415  case AMDGPU::G_SHL:
416  case AMDGPU::G_UADDO:
417  case AMDGPU::G_SADDO:
418  case AMDGPU::G_USUBO:
419  case AMDGPU::G_SSUBO:
420  case AMDGPU::G_UADDE:
421  case AMDGPU::G_SADDE:
422  case AMDGPU::G_USUBE:
423  case AMDGPU::G_SSUBE:
424  if (isSALUMapping(MI))
425  return getDefaultMappingSOP(MI);
427 
428  case AMDGPU::G_FADD:
429  case AMDGPU::G_FSUB:
430  case AMDGPU::G_FPTOSI:
431  case AMDGPU::G_FPTOUI:
432  case AMDGPU::G_FMUL:
433  case AMDGPU::G_FMA:
434  case AMDGPU::G_SITOFP:
435  case AMDGPU::G_UITOFP:
436  case AMDGPU::G_FPTRUNC:
437  case AMDGPU::G_FEXP2:
438  case AMDGPU::G_FLOG2:
439  case AMDGPU::G_INTRINSIC_TRUNC:
440  case AMDGPU::G_INTRINSIC_ROUND:
441  return getDefaultMappingVOP(MI);
442  case AMDGPU::G_IMPLICIT_DEF: {
443  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
444  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
445  break;
446  }
447  case AMDGPU::G_FCONSTANT:
448  case AMDGPU::G_CONSTANT:
449  case AMDGPU::G_FRAME_INDEX:
450  case AMDGPU::G_BLOCK_ADDR: {
451  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
452  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
453  break;
454  }
455  case AMDGPU::G_INSERT: {
456  unsigned BankID = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID :
457  AMDGPU::VGPRRegBankID;
458  unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
459  unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
460  unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
461  OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
462  OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
463  OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize);
464  OpdsMapping[3] = nullptr;
465  break;
466  }
467  case AMDGPU::G_EXTRACT: {
468  unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
469  unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
470  unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
471  OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
472  OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
473  OpdsMapping[2] = nullptr;
474  break;
475  }
476  case AMDGPU::G_MERGE_VALUES: {
477  unsigned Bank = isSALUMapping(MI) ?
478  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
479  unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
480  unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
481 
482  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
483  // Op1 and Dst should use the same register bank.
484  for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i)
485  OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize);
486  break;
487  }
488  case AMDGPU::G_BITCAST:
489  case AMDGPU::G_INTTOPTR:
490  case AMDGPU::G_PTRTOINT:
491  case AMDGPU::G_CTLZ:
492  case AMDGPU::G_CTLZ_ZERO_UNDEF:
493  case AMDGPU::G_CTTZ:
494  case AMDGPU::G_CTTZ_ZERO_UNDEF:
495  case AMDGPU::G_CTPOP:
496  case AMDGPU::G_BSWAP:
497  case AMDGPU::G_FABS:
498  case AMDGPU::G_FNEG: {
499  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
500  unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
501  OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size);
502  break;
503  }
504  case AMDGPU::G_TRUNC: {
505  unsigned Dst = MI.getOperand(0).getReg();
506  unsigned Src = MI.getOperand(1).getReg();
507  unsigned Bank = getRegBankID(Src, MRI, *TRI);
508  unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
509  unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
510  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
511  OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize);
512  break;
513  }
514  case AMDGPU::G_ZEXT:
515  case AMDGPU::G_SEXT:
516  case AMDGPU::G_ANYEXT: {
517  unsigned Dst = MI.getOperand(0).getReg();
518  unsigned Src = MI.getOperand(1).getReg();
519  unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
520  unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
521  unsigned SrcBank = getRegBankID(Src, MRI, *TRI,
522  SrcSize == 1 ? AMDGPU::SGPRRegBankID :
523  AMDGPU::VGPRRegBankID);
524  unsigned DstBank = SrcBank;
525  if (SrcSize == 1) {
526  if (SrcBank == AMDGPU::SGPRRegBankID)
527  DstBank = AMDGPU::VGPRRegBankID;
528  else
529  DstBank = AMDGPU::SGPRRegBankID;
530  }
531 
532  OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, DstSize);
533  OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank, SrcSize);
534  break;
535  }
536  case AMDGPU::G_FCMP: {
537  unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
538  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
539  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1);
540  OpdsMapping[1] = nullptr; // Predicate Operand.
541  OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
542  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
543  break;
544  }
545  case AMDGPU::G_GEP: {
546  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
547  if (!MI.getOperand(i).isReg())
548  continue;
549 
550  unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
551  OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
552  }
553  break;
554  }
555  case AMDGPU::G_STORE: {
556  assert(MI.getOperand(0).isReg());
557  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
558  // FIXME: We need to specify a different reg bank once scalar stores
559  // are supported.
560  const ValueMapping *ValMapping =
561  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
562  // FIXME: Depending on the type of store, the pointer could be in
563  // the SGPR Reg bank.
564  // FIXME: Pointer size should be based on the address space.
565  const ValueMapping *PtrMapping =
566  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
567 
568  OpdsMapping[0] = ValMapping;
569  OpdsMapping[1] = PtrMapping;
570  break;
571  }
572 
573  case AMDGPU::G_ICMP: {
574  unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
575  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
576  unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
577  unsigned Op0Bank = Op2Bank == AMDGPU::SGPRRegBankID &&
578  Op3Bank == AMDGPU::SGPRRegBankID ?
579  AMDGPU::SCCRegBankID : AMDGPU::VCCRegBankID;
580  OpdsMapping[0] = AMDGPU::getValueMapping(Op0Bank, 1);
581  OpdsMapping[1] = nullptr; // Predicate Operand.
582  OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
583  OpdsMapping[3] = AMDGPU::getValueMapping(Op3Bank, Size);
584  break;
585  }
586 
587 
588  case AMDGPU::G_EXTRACT_VECTOR_ELT: {
589  unsigned IdxOp = 2;
590  int64_t Imm;
591  // XXX - Do we really need to fully handle these? The constant case should
592  // be legalized away before RegBankSelect?
593 
594  unsigned OutputBankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
595  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
596 
597  unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
598  OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(0).getReg()).getSizeInBits());
599  OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(1).getReg()).getSizeInBits());
600 
601  // The index can be either if the source vector is VGPR.
602  OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, MRI.getType(MI.getOperand(2).getReg()).getSizeInBits());
603  break;
604  }
605  case AMDGPU::G_INSERT_VECTOR_ELT: {
606  // XXX - Do we really need to fully handle these? The constant case should
607  // be legalized away before RegBankSelect?
608 
609  int64_t Imm;
610 
611  unsigned IdxOp = MI.getOpcode() == AMDGPU::G_EXTRACT_VECTOR_ELT ? 2 : 3;
612  unsigned BankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
613  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
614 
615 
616 
617  // TODO: Can do SGPR indexing, which would obviate the need for the
618  // isConstant check.
619  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
620  unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
621  OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size);
622  }
623 
624 
625  break;
626  }
627  case AMDGPU::G_UNMERGE_VALUES: {
628  unsigned Bank = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID :
629  AMDGPU::VGPRRegBankID;
630 
631  // Op1 and Dst should use the same register bank.
632  // FIXME: Shouldn't this be the default? Why do we need to handle this?
633  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
634  unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
635  OpdsMapping[i] = AMDGPU::getValueMapping(Bank, Size);
636  }
637  break;
638  }
639  case AMDGPU::G_INTRINSIC: {
640  switch (MI.getOperand(1).getIntrinsicID()) {
641  default:
643  case Intrinsic::maxnum:
644  case Intrinsic::minnum:
646  return getDefaultMappingVOP(MI);
648  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
649  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
650  break;
651  }
653  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
654  OpdsMapping[0] = OpdsMapping[2]
655  = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
656  break;
657  }
658  }
659  break;
660  }
661  case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: {
662  switch (MI.getOperand(0).getIntrinsicID()) {
663  default:
666  OpdsMapping[0] = nullptr; // IntrinsicID
667  // FIXME: These are immediate values which can't be read from registers.
668  OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
669  OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
670  // FIXME: Could we support packed types here?
671  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
672  OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
673  // FIXME: These are immediate values which can't be read from registers.
674  OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
675  OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
676  break;
678  OpdsMapping[0] = nullptr; // IntrinsicID
679  // FIXME: These are immediate values which can't be read from registers.
680  OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
681  OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
682  // FIXME: Could we support packed types here?
683  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
684  OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
685  OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
686  OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
687  // FIXME: These are immediate values which can't be read from registers.
688  OpdsMapping[7] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
689  OpdsMapping[8] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
690  break;
691  }
692  break;
693  }
694  case AMDGPU::G_SELECT: {
695  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
696  unsigned Op1Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI,
697  AMDGPU::SGPRRegBankID);
698  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
699  unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
700  bool SGPRSrcs = Op1Bank == AMDGPU::SCCRegBankID &&
701  Op2Bank == AMDGPU::SGPRRegBankID &&
702  Op3Bank == AMDGPU::SGPRRegBankID;
703  unsigned Bank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
704  Op1Bank = SGPRSrcs ? AMDGPU::SCCRegBankID : AMDGPU::VCCRegBankID;
705  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size);
706  OpdsMapping[1] = AMDGPU::getValueMapping(Op1Bank, 1);
707  OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size);
708  OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size);
709  break;
710  }
711 
712  case AMDGPU::G_LOAD:
713  return getInstrMappingForLoad(MI);
714 
715  case AMDGPU::G_ATOMICRMW_XCHG:
716  case AMDGPU::G_ATOMICRMW_ADD:
717  case AMDGPU::G_ATOMICRMW_SUB:
718  case AMDGPU::G_ATOMICRMW_AND:
719  case AMDGPU::G_ATOMICRMW_OR:
720  case AMDGPU::G_ATOMICRMW_XOR:
721  case AMDGPU::G_ATOMICRMW_MAX:
722  case AMDGPU::G_ATOMICRMW_MIN:
723  case AMDGPU::G_ATOMICRMW_UMAX:
724  case AMDGPU::G_ATOMICRMW_UMIN:
725  case AMDGPU::G_ATOMIC_CMPXCHG: {
726  return getDefaultMappingAllVGPR(MI);
727  }
728  case AMDGPU::G_BRCOND: {
729  unsigned Bank = getRegBankID(MI.getOperand(0).getReg(), MRI, *TRI,
730  AMDGPU::SGPRRegBankID);
731  assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1);
732  if (Bank != AMDGPU::SCCRegBankID)
733  Bank = AMDGPU::VCCRegBankID;
734 
735  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, 1);
736  break;
737  }
738  }
739 
740  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
741  MI.getNumOperands());
742 }
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
This function must return a legal mapping, because AMDGPURegisterBankInfo::getInstrAlternativeMapping...
uint64_t CallInst * C
Interface definition for SIRegisterInfo.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
#define LLVM_FALLTHROUGH
Definition: Compiler.h:86
Helper class that represents how the value of an instruction may be mapped and what is the related co...
void push_back(const T &Elt)
Definition: SmallVector.h:218
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
unsigned const TargetRegisterInfo * TRI
bool isIntrinsicID() const
unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const override
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
A description of a memory reference used in the backend.
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:412
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
static bool isConstant(const MachineOperand &MO, int64_t &C)
bool isSGPRClass(const TargetRegisterClass *RC) const
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
static bool isInstrUniform(const MachineInstr &MI)
unsigned const MachineRegisterInfo * MRI
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isUniformMMO(const MachineMemOperand *MMO)
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:549
const ValueMapping & getValueMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const
The most common ValueMapping consists of a single PartialMapping.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isValid() const
Check whether this object is valid.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:534
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
Intrinsic::ID getIntrinsicID() const
This class implements the register bank concept.
Definition: RegisterBank.h:29
Helper struct that represents how a value is mapped through different register banks.
AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI)
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override
Get a register bank that covers RC.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
#define I(x, y, z)
Definition: MD5.cpp:58
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
uint32_t Size
Definition: Profile.cpp:47
This class provides the information for the target register banks.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Helper struct that represents how a value is mapped through different register banks.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
IRTranslator LLVM IR MI
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition: Constants.h:157
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
const ConstantInt * getCImm() const
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:48