LLVM  8.0.0svn
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  // SGPRRegBank with size 1 is actually vcc or another 64-bit sgpr written by
81  // the valu.
82  if (Size == 1 && Dst.getID() == AMDGPU::SCCRegBankID &&
83  Src.getID() == AMDGPU::SGPRRegBankID)
85 
86  return RegisterBankInfo::copyCost(Dst, Src, Size);
87 }
88 
90  const TargetRegisterClass &RC) const {
91 
92  if (TRI->isSGPRClass(&RC))
93  return getRegBank(AMDGPU::SGPRRegBankID);
94 
95  return getRegBank(AMDGPU::VGPRRegBankID);
96 }
97 
100  const MachineInstr &MI) const {
101 
102  const MachineFunction &MF = *MI.getParent()->getParent();
103  const MachineRegisterInfo &MRI = MF.getRegInfo();
104 
105 
106  InstructionMappings AltMappings;
107  switch (MI.getOpcode()) {
108  case TargetOpcode::G_LOAD: {
109  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
110  // FIXME: Should we be hard coding the size for these mappings?
111  const InstructionMapping &SSMapping = getInstructionMapping(
112  1, 1, getOperandsMapping(
113  {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
114  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
115  2); // Num Operands
116  AltMappings.push_back(&SSMapping);
117 
118  const InstructionMapping &VVMapping = getInstructionMapping(
119  2, 1, getOperandsMapping(
120  {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
121  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
122  2); // Num Operands
123  AltMappings.push_back(&VVMapping);
124 
125  // FIXME: Should this be the pointer-size (64-bits) or the size of the
126  // register that will hold the bufffer resourc (128-bits).
127  const InstructionMapping &VSMapping = getInstructionMapping(
128  3, 1, getOperandsMapping(
129  {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
130  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
131  2); // Num Operands
132  AltMappings.push_back(&VSMapping);
133 
134  return AltMappings;
135 
136  }
137  case TargetOpcode::G_ICMP: {
138  unsigned Size = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
139  const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
140  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
141  nullptr, // Predicate operand.
142  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
143  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
144  4); // Num Operands
145  AltMappings.push_back(&SSMapping);
146 
147  const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
148  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
149  nullptr, // Predicate operand.
150  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
151  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
152  4); // Num Operands
153  AltMappings.push_back(&SVMapping);
154 
155  const InstructionMapping &VSMapping = getInstructionMapping(3, 1,
156  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
157  nullptr, // Predicate operand.
158  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
159  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
160  4); // Num Operands
161  AltMappings.push_back(&VSMapping);
162 
163  const InstructionMapping &VVMapping = getInstructionMapping(4, 1,
164  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
165  nullptr, // Predicate operand.
166  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
167  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
168  4); // Num Operands
169  AltMappings.push_back(&VVMapping);
170 
171  return AltMappings;
172  }
173  case TargetOpcode::G_SELECT: {
174  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
175  const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
176  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
177  AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
178  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
179  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
180  4); // Num Operands
181  AltMappings.push_back(&SSMapping);
182 
183  const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
184  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
185  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
186  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
187  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
188  4); // Num Operands
189  AltMappings.push_back(&SVMapping);
190 
191  const InstructionMapping &VSMapping = getInstructionMapping(2, 1,
192  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
193  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
194  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
195  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
196  4); // Num Operands
197  AltMappings.push_back(&VSMapping);
198 
199  const InstructionMapping &VVMapping = getInstructionMapping(2, 1,
200  getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
201  AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
202  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
203  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
204  4); // Num Operands
205  AltMappings.push_back(&VVMapping);
206 
207  return AltMappings;
208  }
209  default:
210  break;
211  }
213 }
214 
215 void AMDGPURegisterBankInfo::applyMappingImpl(
216  const OperandsMapper &OpdMapper) const {
217  return applyDefaultMapping(OpdMapper);
218 }
219 
220 static bool isInstrUniform(const MachineInstr &MI) {
221  if (!MI.hasOneMemOperand())
222  return false;
223 
224  const MachineMemOperand *MMO = *MI.memoperands_begin();
225  return AMDGPUInstrInfo::isUniformMMO(MMO);
226 }
227 
228 bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const {
229  const MachineFunction &MF = *MI.getParent()->getParent();
230  const MachineRegisterInfo &MRI = MF.getRegInfo();
231  for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) {
232  if (!MI.getOperand(i).isReg())
233  continue;
234  unsigned Reg = MI.getOperand(i).getReg();
235  const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI);
236  if (Bank && Bank->getID() != AMDGPU::SGPRRegBankID)
237  return false;
238  }
239  return true;
240 }
241 
243 AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const {
244  const MachineFunction &MF = *MI.getParent()->getParent();
245  const MachineRegisterInfo &MRI = MF.getRegInfo();
247 
248  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
249  unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
250  OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
251  }
252  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
253  MI.getNumOperands());
254 }
255 
257 AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const {
258  const MachineFunction &MF = *MI.getParent()->getParent();
259  const MachineRegisterInfo &MRI = MF.getRegInfo();
261  unsigned OpdIdx = 0;
262 
263  unsigned Size0 = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
264  OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size0);
265 
266  if (MI.getOperand(OpdIdx).isIntrinsicID())
267  OpdsMapping[OpdIdx++] = nullptr;
268 
269  unsigned Reg1 = MI.getOperand(OpdIdx).getReg();
270  unsigned Size1 = getSizeInBits(Reg1, MRI, *TRI);
271  unsigned Bank1 = getRegBankID(Reg1, MRI, *TRI);
272  OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(Bank1, Size1);
273 
274  for (unsigned e = MI.getNumOperands(); OpdIdx != e; ++OpdIdx) {
275  unsigned Size = getSizeInBits(MI.getOperand(OpdIdx).getReg(), MRI, *TRI);
276  OpdsMapping[OpdIdx] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
277  }
278 
279  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
280  MI.getNumOperands());
281 }
282 
284 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
285 
286  const MachineFunction &MF = *MI.getParent()->getParent();
287  const MachineRegisterInfo &MRI = MF.getRegInfo();
289  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
290  unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
291 
292  const ValueMapping *ValMapping;
293  const ValueMapping *PtrMapping;
294 
295  if (isInstrUniform(MI)) {
296  // We have a uniform instruction so we want to use an SMRD load
297  ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
298  PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
299  } else {
300  ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
301  // FIXME: What would happen if we used SGPRRegBankID here?
302  PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
303  }
304 
305  OpdsMapping[0] = ValMapping;
306  OpdsMapping[1] = PtrMapping;
308  1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
309  return Mapping;
310 
311  // FIXME: Do we want to add a mapping for FLAT load, or should we just
312  // handle that during instruction selection?
313 }
314 
315 unsigned
316 AMDGPURegisterBankInfo::getRegBankID(unsigned Reg,
317  const MachineRegisterInfo &MRI,
318  const TargetRegisterInfo &TRI,
319  unsigned Default) const {
320 
321  const RegisterBank *Bank = getRegBank(Reg, MRI, TRI);
322  return Bank ? Bank->getID() : Default;
323 }
324 
325 ///
326 /// This function must return a legal mapping, because
327 /// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called
328 /// in RegBankSelect::Mode::Fast. Any mapping that would cause a
329 /// VGPR to SGPR generated is illegal.
330 ///
334 
335  if (Mapping.isValid())
336  return Mapping;
337 
338  const MachineFunction &MF = *MI.getParent()->getParent();
339  const MachineRegisterInfo &MRI = MF.getRegInfo();
341 
342  switch (MI.getOpcode()) {
343  default:
345  case AMDGPU::G_ADD:
346  case AMDGPU::G_SUB:
347  case AMDGPU::G_MUL:
348  case AMDGPU::G_AND:
349  case AMDGPU::G_OR:
350  case AMDGPU::G_XOR:
351  case AMDGPU::G_SHL:
352  if (isSALUMapping(MI))
353  return getDefaultMappingSOP(MI);
354  // Fall-through
355 
356  case AMDGPU::G_FADD:
357  case AMDGPU::G_FPTOSI:
358  case AMDGPU::G_FPTOUI:
359  case AMDGPU::G_FMUL:
360  return getDefaultMappingVOP(MI);
361  case AMDGPU::G_IMPLICIT_DEF: {
362  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
363  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
364  break;
365  }
366  case AMDGPU::G_FCONSTANT:
367  case AMDGPU::G_CONSTANT: {
368  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
369  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
370  break;
371  }
372  case AMDGPU::G_INSERT: {
373  unsigned BankID = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID :
374  AMDGPU::VGPRRegBankID;
375  unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
376  unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
377  unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
378  OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
379  OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
380  OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize);
381  OpdsMapping[3] = nullptr;
382  break;
383  }
384  case AMDGPU::G_EXTRACT: {
385  unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
386  unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
387  unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
388  OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
389  OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
390  OpdsMapping[2] = nullptr;
391  break;
392  }
393  case AMDGPU::G_MERGE_VALUES: {
394  unsigned Bank = isSALUMapping(MI) ?
395  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
396  unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
397  unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
398 
399  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
400  // Op1 and Dst should use the same register bank.
401  for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i)
402  OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize);
403  break;
404  }
405  case AMDGPU::G_BITCAST: {
406  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
407  unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
408  OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size);
409  break;
410  }
411  case AMDGPU::G_TRUNC: {
412  unsigned Dst = MI.getOperand(0).getReg();
413  unsigned Src = MI.getOperand(1).getReg();
414  unsigned Bank = getRegBankID(Src, MRI, *TRI);
415  unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
416  unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
417  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
418  OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize);
419  break;
420  }
421  case AMDGPU::G_ZEXT: {
422  unsigned Dst = MI.getOperand(0).getReg();
423  unsigned Src = MI.getOperand(1).getReg();
424  unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
425  unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
426  unsigned SrcBank = getRegBankID(Src, MRI, *TRI,
427  SrcSize == 1 ? AMDGPU::SGPRRegBankID :
428  AMDGPU::VGPRRegBankID);
429  unsigned DstBank = SrcBank;
430  if (SrcSize == 1) {
431  if (SrcBank == AMDGPU::SGPRRegBankID)
432  DstBank = AMDGPU::VGPRRegBankID;
433  else
434  DstBank = AMDGPU::SGPRRegBankID;
435  }
436 
437  OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, DstSize);
438  OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank, SrcSize);
439  break;
440  }
441  case AMDGPU::G_FCMP: {
442  unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
443  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
444  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 1);
445  OpdsMapping[1] = nullptr; // Predicate Operand.
446  OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
447  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
448  break;
449  }
450  case AMDGPU::G_GEP: {
451  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
452  if (!MI.getOperand(i).isReg())
453  continue;
454 
455  unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
456  OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
457  }
458  break;
459  }
460  case AMDGPU::G_STORE: {
461  assert(MI.getOperand(0).isReg());
462  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
463  // FIXME: We need to specify a different reg bank once scalar stores
464  // are supported.
465  const ValueMapping *ValMapping =
466  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
467  // FIXME: Depending on the type of store, the pointer could be in
468  // the SGPR Reg bank.
469  // FIXME: Pointer size should be based on the address space.
470  const ValueMapping *PtrMapping =
471  AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
472 
473  OpdsMapping[0] = ValMapping;
474  OpdsMapping[1] = PtrMapping;
475  break;
476  }
477 
478  case AMDGPU::G_ICMP: {
479  unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
480  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
481  unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
482  unsigned Op0Bank = Op2Bank == AMDGPU::SGPRRegBankID &&
483  Op3Bank == AMDGPU::SGPRRegBankID ?
484  AMDGPU::SCCRegBankID : AMDGPU::VGPRRegBankID;
485  OpdsMapping[0] = AMDGPU::getValueMapping(Op0Bank, 1);
486  OpdsMapping[1] = nullptr; // Predicate Operand.
487  OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
488  OpdsMapping[3] = AMDGPU::getValueMapping(Op3Bank, Size);
489  break;
490  }
491 
492 
493  case AMDGPU::G_EXTRACT_VECTOR_ELT: {
494  unsigned IdxOp = 2;
495  int64_t Imm;
496  // XXX - Do we really need to fully handle these? The constant case should
497  // be legalized away before RegBankSelect?
498 
499  unsigned OutputBankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
500  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
501 
502  unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
503  OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(0).getReg()).getSizeInBits());
504  OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(1).getReg()).getSizeInBits());
505 
506  // The index can be either if the source vector is VGPR.
507  OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, MRI.getType(MI.getOperand(2).getReg()).getSizeInBits());
508  break;
509  }
510  case AMDGPU::G_INSERT_VECTOR_ELT: {
511  // XXX - Do we really need to fully handle these? The constant case should
512  // be legalized away before RegBankSelect?
513 
514  int64_t Imm;
515 
516  unsigned IdxOp = MI.getOpcode() == AMDGPU::G_EXTRACT_VECTOR_ELT ? 2 : 3;
517  unsigned BankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
518  AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
519 
520 
521 
522  // TODO: Can do SGPR indexing, which would obviate the need for the
523  // isConstant check.
524  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
525  unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
526  OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size);
527  }
528 
529 
530  break;
531  }
532  case AMDGPU::G_INTRINSIC: {
533  switch (MI.getOperand(1).getIntrinsicID()) {
534  default:
536  case Intrinsic::maxnum:
537  case Intrinsic::minnum:
538  case Intrinsic::amdgcn_cvt_pkrtz:
539  return getDefaultMappingVOP(MI);
540  case Intrinsic::amdgcn_kernarg_segment_ptr: {
541  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
542  OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
543  break;
544  }
545  }
546  break;
547  }
548  case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: {
549  switch (MI.getOperand(0).getIntrinsicID()) {
550  default:
552  case Intrinsic::amdgcn_exp_compr:
553  OpdsMapping[0] = nullptr; // IntrinsicID
554  // FIXME: These are immediate values which can't be read from registers.
555  OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
556  OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
557  // FIXME: Could we support packed types here?
558  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
559  OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
560  // FIXME: These are immediate values which can't be read from registers.
561  OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
562  OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
563  break;
564  case Intrinsic::amdgcn_exp:
565  OpdsMapping[0] = nullptr; // IntrinsicID
566  // FIXME: These are immediate values which can't be read from registers.
567  OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
568  OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
569  // FIXME: Could we support packed types here?
570  OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
571  OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
572  OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
573  OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
574  // FIXME: These are immediate values which can't be read from registers.
575  OpdsMapping[7] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
576  OpdsMapping[8] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
577  break;
578  }
579  break;
580  }
581  case AMDGPU::G_SELECT: {
582  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
583  unsigned Op1Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI,
584  AMDGPU::SGPRRegBankID);
585  unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
586  unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
587  bool SGPRSrcs = Op1Bank == AMDGPU::SCCRegBankID &&
588  Op2Bank == AMDGPU::SGPRRegBankID &&
589  Op3Bank == AMDGPU::SGPRRegBankID;
590  unsigned Bank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
591  Op1Bank = SGPRSrcs ? AMDGPU::SCCRegBankID : AMDGPU::SGPRRegBankID;
592  OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size);
593  OpdsMapping[1] = AMDGPU::getValueMapping(Op1Bank, 1);
594  OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size);
595  OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size);
596  break;
597  }
598 
599  case AMDGPU::G_LOAD:
600  return getInstrMappingForLoad(MI);
601  }
602 
603  return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
604  MI.getNumOperands());
605 }
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
This function must return a legal mapping, because AMDGPURegisterBankInfo::getInstrAlternativeMapping...
uint64_t CallInst * C
void push_back(const T &Elt)
Definition: SmallVector.h:218
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.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
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
Access to explicit operands of the instruction.
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.
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...
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE maxNum semantics.
Definition: APFloat.h:1238
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.
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
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE minNum semantics.
Definition: APFloat.h:1227
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:48