Line data Source code
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"
19 : #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
20 : #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
21 : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
22 : #include "llvm/CodeGen/TargetRegisterInfo.h"
23 : #include "llvm/CodeGen/TargetSubtargetInfo.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 :
34 2492 : AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI)
35 : : AMDGPUGenRegisterBankInfo(),
36 2492 : TRI(static_cast<const SIRegisterInfo*>(&TRI)) {
37 :
38 : // HACK: Until this is fully tablegen'd
39 : static bool AlreadyInit = false;
40 2492 : if (AlreadyInit)
41 : return;
42 :
43 2406 : 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 4 : static bool isConstant(const MachineOperand &MO, int64_t &C) {
56 5 : const MachineFunction *MF = MO.getParent()->getParent()->getParent();
57 5 : const MachineRegisterInfo &MRI = MF->getRegInfo();
58 5 : const MachineInstr *Def = MRI.getVRegDef(MO.getReg());
59 5 : if (!Def)
60 : return false;
61 :
62 8 : if (Def->getOpcode() == AMDGPU::G_CONSTANT) {
63 3 : C = Def->getOperand(1).getCImm()->getSExtValue();
64 3 : return true;
65 : }
66 :
67 1 : if (Def->getOpcode() == AMDGPU::COPY)
68 2 : return isConstant(Def->getOperand(1), C);
69 :
70 : return false;
71 : }
72 :
73 107 : unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &Dst,
74 : const RegisterBank &Src,
75 : unsigned Size) const {
76 107 : if (Dst.getID() == AMDGPU::SGPRRegBankID &&
77 45 : Src.getID() == AMDGPU::VGPRRegBankID)
78 : return std::numeric_limits<unsigned>::max();
79 :
80 : // SGPRRegBank with size 1 is actually vcc or another 64-bit sgpr written by
81 : // the valu.
82 77 : if (Size == 1 && Dst.getID() == AMDGPU::SCCRegBankID &&
83 4 : Src.getID() == AMDGPU::SGPRRegBankID)
84 : return std::numeric_limits<unsigned>::max();
85 :
86 73 : return RegisterBankInfo::copyCost(Dst, Src, Size);
87 : }
88 :
89 629 : const RegisterBank &AMDGPURegisterBankInfo::getRegBankFromRegClass(
90 : const TargetRegisterClass &RC) const {
91 :
92 629 : if (TRI->isSGPRClass(&RC))
93 306 : return getRegBank(AMDGPU::SGPRRegBankID);
94 :
95 323 : return getRegBank(AMDGPU::VGPRRegBankID);
96 : }
97 :
98 : RegisterBankInfo::InstructionMappings
99 264 : AMDGPURegisterBankInfo::getInstrAlternativeMappings(
100 : const MachineInstr &MI) const {
101 :
102 264 : const MachineFunction &MF = *MI.getParent()->getParent();
103 264 : const MachineRegisterInfo &MRI = MF.getRegInfo();
104 :
105 :
106 : InstructionMappings AltMappings;
107 528 : switch (MI.getOpcode()) {
108 0 : case TargetOpcode::G_LOAD: {
109 0 : 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 0 : {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
114 0 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
115 0 : 2); // Num Operands
116 0 : AltMappings.push_back(&SSMapping);
117 :
118 : const InstructionMapping &VVMapping = getInstructionMapping(
119 : 2, 1, getOperandsMapping(
120 0 : {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
121 0 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
122 0 : 2); // Num Operands
123 0 : 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 0 : {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
130 0 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
131 0 : 2); // Num Operands
132 0 : AltMappings.push_back(&VSMapping);
133 :
134 : return AltMappings;
135 :
136 : }
137 13 : case TargetOpcode::G_ICMP: {
138 13 : unsigned Size = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
139 : const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
140 13 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
141 : nullptr, // Predicate operand.
142 13 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
143 13 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
144 13 : 4); // Num Operands
145 13 : AltMappings.push_back(&SSMapping);
146 :
147 : const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
148 13 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
149 : nullptr, // Predicate operand.
150 13 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
151 13 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
152 13 : 4); // Num Operands
153 13 : AltMappings.push_back(&SVMapping);
154 :
155 : const InstructionMapping &VSMapping = getInstructionMapping(3, 1,
156 13 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
157 : nullptr, // Predicate operand.
158 13 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
159 13 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
160 13 : 4); // Num Operands
161 13 : AltMappings.push_back(&VSMapping);
162 :
163 : const InstructionMapping &VVMapping = getInstructionMapping(4, 1,
164 13 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
165 : nullptr, // Predicate operand.
166 13 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
167 13 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
168 13 : 4); // Num Operands
169 13 : AltMappings.push_back(&VVMapping);
170 :
171 : return AltMappings;
172 : }
173 8 : case TargetOpcode::G_SELECT: {
174 8 : unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
175 : const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
176 8 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
177 8 : AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
178 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
179 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
180 8 : 4); // Num Operands
181 8 : AltMappings.push_back(&SSMapping);
182 :
183 : const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
184 8 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
185 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
186 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
187 8 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
188 8 : 4); // Num Operands
189 8 : AltMappings.push_back(&SVMapping);
190 :
191 : const InstructionMapping &VSMapping = getInstructionMapping(2, 1,
192 8 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
193 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
194 8 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
195 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
196 8 : 4); // Num Operands
197 8 : AltMappings.push_back(&VSMapping);
198 :
199 : const InstructionMapping &VVMapping = getInstructionMapping(2, 1,
200 8 : getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
201 8 : AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
202 8 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
203 8 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
204 8 : 4); // Num Operands
205 8 : AltMappings.push_back(&VVMapping);
206 :
207 : return AltMappings;
208 : }
209 : default:
210 : break;
211 : }
212 243 : return RegisterBankInfo::getInstrAlternativeMappings(MI);
213 : }
214 :
215 356 : void AMDGPURegisterBankInfo::applyMappingImpl(
216 : const OperandsMapper &OpdMapper) const {
217 356 : return applyDefaultMapping(OpdMapper);
218 : }
219 :
220 27 : static bool isInstrUniform(const MachineInstr &MI) {
221 27 : if (!MI.hasOneMemOperand())
222 : return false;
223 :
224 27 : const MachineMemOperand *MMO = *MI.memoperands_begin();
225 27 : return AMDGPUInstrInfo::isUniformMMO(MMO);
226 : }
227 :
228 67 : bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const {
229 67 : const MachineFunction &MF = *MI.getParent()->getParent();
230 67 : const MachineRegisterInfo &MRI = MF.getRegInfo();
231 198 : for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) {
232 354 : if (!MI.getOperand(i).isReg())
233 : continue;
234 173 : unsigned Reg = MI.getOperand(i).getReg();
235 173 : const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI);
236 173 : if (Bank && Bank->getID() != AMDGPU::SGPRRegBankID)
237 : return false;
238 : }
239 : return true;
240 : }
241 :
242 : const RegisterBankInfo::InstructionMapping &
243 11 : AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const {
244 11 : const MachineFunction &MF = *MI.getParent()->getParent();
245 11 : const MachineRegisterInfo &MRI = MF.getRegInfo();
246 11 : SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
247 :
248 44 : for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
249 66 : unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
250 33 : OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
251 : }
252 : return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
253 11 : MI.getNumOperands());
254 : }
255 :
256 : const RegisterBankInfo::InstructionMapping &
257 81 : AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const {
258 81 : const MachineFunction &MF = *MI.getParent()->getParent();
259 81 : const MachineRegisterInfo &MRI = MF.getRegInfo();
260 81 : SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
261 : unsigned OpdIdx = 0;
262 :
263 81 : unsigned Size0 = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
264 81 : OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size0);
265 :
266 162 : if (MI.getOperand(OpdIdx).isIntrinsicID())
267 24 : OpdsMapping[OpdIdx++] = nullptr;
268 :
269 81 : unsigned Reg1 = MI.getOperand(OpdIdx).getReg();
270 81 : unsigned Size1 = getSizeInBits(Reg1, MRI, *TRI);
271 81 : unsigned Bank1 = getRegBankID(Reg1, MRI, *TRI);
272 162 : OpdsMapping[OpdIdx++] = AMDGPU::getValueMapping(Bank1, Size1);
273 :
274 154 : for (unsigned e = MI.getNumOperands(); OpdIdx != e; ++OpdIdx) {
275 146 : unsigned Size = getSizeInBits(MI.getOperand(OpdIdx).getReg(), MRI, *TRI);
276 73 : OpdsMapping[OpdIdx] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
277 : }
278 :
279 : return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
280 81 : MI.getNumOperands());
281 : }
282 :
283 : const RegisterBankInfo::InstructionMapping &
284 27 : AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
285 :
286 27 : const MachineFunction &MF = *MI.getParent()->getParent();
287 27 : const MachineRegisterInfo &MRI = MF.getRegInfo();
288 27 : SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
289 27 : unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
290 27 : unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
291 :
292 : const ValueMapping *ValMapping;
293 : const ValueMapping *PtrMapping;
294 :
295 27 : if (isInstrUniform(MI)) {
296 : // We have a uniform instruction so we want to use an SMRD load
297 26 : ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
298 26 : PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
299 : } else {
300 1 : ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
301 : // FIXME: What would happen if we used SGPRRegBankID here?
302 1 : PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
303 : }
304 :
305 27 : OpdsMapping[0] = ValMapping;
306 27 : OpdsMapping[1] = PtrMapping;
307 : const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
308 27 : 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
309 27 : 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 218 : AMDGPURegisterBankInfo::getRegBankID(unsigned Reg,
317 : const MachineRegisterInfo &MRI,
318 : const TargetRegisterInfo &TRI,
319 : unsigned Default) const {
320 :
321 218 : const RegisterBank *Bank = getRegBank(Reg, MRI, TRI);
322 218 : 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 : ///
331 : const RegisterBankInfo::InstructionMapping &
332 741 : AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
333 741 : const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
334 :
335 : if (Mapping.isValid())
336 : return Mapping;
337 :
338 356 : const MachineFunction &MF = *MI.getParent()->getParent();
339 356 : const MachineRegisterInfo &MRI = MF.getRegInfo();
340 356 : SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
341 :
342 712 : switch (MI.getOpcode()) {
343 0 : default:
344 0 : return getInvalidInstructionMapping();
345 44 : 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 44 : if (isSALUMapping(MI))
353 11 : 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 57 : return getDefaultMappingVOP(MI);
361 15 : case AMDGPU::G_IMPLICIT_DEF: {
362 30 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
363 15 : OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
364 15 : break;
365 : }
366 64 : case AMDGPU::G_FCONSTANT:
367 : case AMDGPU::G_CONSTANT: {
368 128 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
369 64 : OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
370 64 : break;
371 : }
372 10 : case AMDGPU::G_INSERT: {
373 10 : unsigned BankID = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID :
374 : AMDGPU::VGPRRegBankID;
375 10 : unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
376 10 : unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
377 10 : unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
378 10 : OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
379 10 : OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
380 10 : OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize);
381 10 : OpdsMapping[3] = nullptr;
382 10 : break;
383 : }
384 13 : case AMDGPU::G_EXTRACT: {
385 13 : unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
386 13 : unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
387 13 : unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
388 13 : OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize);
389 13 : OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize);
390 13 : OpdsMapping[2] = nullptr;
391 13 : break;
392 : }
393 4 : case AMDGPU::G_MERGE_VALUES: {
394 4 : unsigned Bank = isSALUMapping(MI) ?
395 : AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
396 4 : unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
397 8 : unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
398 :
399 4 : OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
400 : // Op1 and Dst should use the same register bank.
401 12 : for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i)
402 16 : OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize);
403 : break;
404 : }
405 8 : case AMDGPU::G_INTTOPTR:
406 : case AMDGPU::G_BITCAST: {
407 8 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
408 8 : unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI);
409 8 : OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size);
410 8 : break;
411 : }
412 4 : case AMDGPU::G_TRUNC: {
413 4 : unsigned Dst = MI.getOperand(0).getReg();
414 4 : unsigned Src = MI.getOperand(1).getReg();
415 4 : unsigned Bank = getRegBankID(Src, MRI, *TRI);
416 4 : unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
417 4 : unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
418 4 : OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize);
419 4 : OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize);
420 4 : break;
421 : }
422 4 : case AMDGPU::G_ZEXT: {
423 4 : unsigned Dst = MI.getOperand(0).getReg();
424 4 : unsigned Src = MI.getOperand(1).getReg();
425 4 : unsigned DstSize = getSizeInBits(Dst, MRI, *TRI);
426 4 : unsigned SrcSize = getSizeInBits(Src, MRI, *TRI);
427 8 : unsigned SrcBank = getRegBankID(Src, MRI, *TRI,
428 : SrcSize == 1 ? AMDGPU::SGPRRegBankID :
429 : AMDGPU::VGPRRegBankID);
430 : unsigned DstBank = SrcBank;
431 4 : if (SrcSize == 1) {
432 0 : if (SrcBank == AMDGPU::SGPRRegBankID)
433 : DstBank = AMDGPU::VGPRRegBankID;
434 : else
435 : DstBank = AMDGPU::SGPRRegBankID;
436 : }
437 :
438 4 : OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, DstSize);
439 4 : OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank, SrcSize);
440 4 : break;
441 : }
442 6 : case AMDGPU::G_FCMP: {
443 6 : unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
444 6 : unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
445 6 : OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 1);
446 6 : OpdsMapping[1] = nullptr; // Predicate Operand.
447 6 : OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
448 6 : OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
449 6 : break;
450 : }
451 24 : case AMDGPU::G_GEP: {
452 96 : for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
453 144 : if (!MI.getOperand(i).isReg())
454 : continue;
455 :
456 144 : unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
457 72 : OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
458 : }
459 : break;
460 : }
461 12 : case AMDGPU::G_STORE: {
462 : assert(MI.getOperand(0).isReg());
463 12 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
464 : // FIXME: We need to specify a different reg bank once scalar stores
465 : // are supported.
466 : const ValueMapping *ValMapping =
467 12 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
468 : // FIXME: Depending on the type of store, the pointer could be in
469 : // the SGPR Reg bank.
470 : // FIXME: Pointer size should be based on the address space.
471 : const ValueMapping *PtrMapping =
472 12 : AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
473 :
474 12 : OpdsMapping[0] = ValMapping;
475 12 : OpdsMapping[1] = PtrMapping;
476 12 : break;
477 : }
478 :
479 26 : case AMDGPU::G_ICMP: {
480 26 : unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
481 26 : unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
482 26 : unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
483 52 : unsigned Op0Bank = Op2Bank == AMDGPU::SGPRRegBankID &&
484 26 : Op3Bank == AMDGPU::SGPRRegBankID ?
485 : AMDGPU::SCCRegBankID : AMDGPU::VGPRRegBankID;
486 26 : OpdsMapping[0] = AMDGPU::getValueMapping(Op0Bank, 1);
487 26 : OpdsMapping[1] = nullptr; // Predicate Operand.
488 26 : OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
489 26 : OpdsMapping[3] = AMDGPU::getValueMapping(Op3Bank, Size);
490 26 : break;
491 : }
492 :
493 :
494 2 : case AMDGPU::G_EXTRACT_VECTOR_ELT: {
495 : unsigned IdxOp = 2;
496 : int64_t Imm;
497 : // XXX - Do we really need to fully handle these? The constant case should
498 : // be legalized away before RegBankSelect?
499 :
500 2 : unsigned OutputBankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
501 : AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
502 :
503 2 : unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
504 6 : OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(0).getReg()).getSizeInBits());
505 6 : OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, MRI.getType(MI.getOperand(1).getReg()).getSizeInBits());
506 :
507 : // The index can be either if the source vector is VGPR.
508 6 : OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, MRI.getType(MI.getOperand(2).getReg()).getSizeInBits());
509 : break;
510 : }
511 7 : case AMDGPU::G_INSERT_VECTOR_ELT: {
512 : // XXX - Do we really need to fully handle these? The constant case should
513 : // be legalized away before RegBankSelect?
514 :
515 : int64_t Imm;
516 :
517 7 : unsigned IdxOp = MI.getOpcode() == AMDGPU::G_EXTRACT_VECTOR_ELT ? 2 : 3;
518 7 : unsigned BankID = isSALUMapping(MI) && isConstant(MI.getOperand(IdxOp), Imm) ?
519 : AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
520 :
521 :
522 :
523 : // TODO: Can do SGPR indexing, which would obviate the need for the
524 : // isConstant check.
525 35 : for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
526 56 : unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI);
527 28 : OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size);
528 : }
529 :
530 :
531 : break;
532 : }
533 38 : case AMDGPU::G_INTRINSIC: {
534 38 : switch (MI.getOperand(1).getIntrinsicID()) {
535 0 : default:
536 0 : return getInvalidInstructionMapping();
537 24 : case Intrinsic::maxnum:
538 : case Intrinsic::minnum:
539 : case Intrinsic::amdgcn_cvt_pkrtz:
540 24 : return getDefaultMappingVOP(MI);
541 14 : case Intrinsic::amdgcn_kernarg_segment_ptr: {
542 28 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
543 14 : OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
544 : break;
545 : }
546 : }
547 14 : break;
548 : }
549 8 : case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: {
550 8 : switch (MI.getOperand(0).getIntrinsicID()) {
551 0 : default:
552 0 : return getInvalidInstructionMapping();
553 : case Intrinsic::amdgcn_exp_compr:
554 4 : OpdsMapping[0] = nullptr; // IntrinsicID
555 : // FIXME: These are immediate values which can't be read from registers.
556 4 : OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
557 4 : OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
558 : // FIXME: Could we support packed types here?
559 4 : OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
560 4 : OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
561 : // FIXME: These are immediate values which can't be read from registers.
562 4 : OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
563 4 : OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
564 4 : break;
565 : case Intrinsic::amdgcn_exp:
566 4 : OpdsMapping[0] = nullptr; // IntrinsicID
567 : // FIXME: These are immediate values which can't be read from registers.
568 4 : OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
569 4 : OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
570 : // FIXME: Could we support packed types here?
571 4 : OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
572 4 : OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
573 4 : OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
574 4 : OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32);
575 : // FIXME: These are immediate values which can't be read from registers.
576 4 : OpdsMapping[7] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
577 4 : OpdsMapping[8] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32);
578 4 : break;
579 : }
580 : break;
581 : }
582 16 : case AMDGPU::G_SELECT: {
583 16 : unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
584 16 : unsigned Op1Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI,
585 : AMDGPU::SGPRRegBankID);
586 16 : unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
587 16 : unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
588 32 : bool SGPRSrcs = Op1Bank == AMDGPU::SCCRegBankID &&
589 16 : Op2Bank == AMDGPU::SGPRRegBankID &&
590 : Op3Bank == AMDGPU::SGPRRegBankID;
591 : unsigned Bank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID;
592 16 : Op1Bank = SGPRSrcs ? AMDGPU::SCCRegBankID : AMDGPU::SGPRRegBankID;
593 16 : OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size);
594 16 : OpdsMapping[1] = AMDGPU::getValueMapping(Op1Bank, 1);
595 16 : OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size);
596 16 : OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size);
597 16 : break;
598 : }
599 :
600 27 : case AMDGPU::G_LOAD:
601 27 : return getInstrMappingForLoad(MI);
602 : }
603 :
604 : return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
605 474 : MI.getNumOperands());
606 : }
|