]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r301441, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AMDGPU / AMDGPURegisterBankInfo.cpp
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 "SIRegisterInfo.h"
18 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
19 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/Target/TargetRegisterInfo.h"
22 #include "llvm/Target/TargetSubtargetInfo.h"
23
24 #define GET_TARGET_REGBANK_IMPL
25 #include "AMDGPUGenRegisterBank.inc"
26
27 // This file will be TableGen'ed at some point.
28 #include "AMDGPUGenRegisterBankInfo.def"
29
30 using namespace llvm;
31
32 #ifndef LLVM_BUILD_GLOBAL_ISEL
33 #error "You shouldn't build this"
34 #endif
35
36 AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI)
37     : AMDGPUGenRegisterBankInfo(),
38       TRI(static_cast<const SIRegisterInfo*>(&TRI)) {
39
40   // HACK: Until this is fully tablegen'd
41   static bool AlreadyInit = false;
42   if (AlreadyInit)
43     return;
44
45   AlreadyInit = true;
46
47   const RegisterBank &RBSGPR = getRegBank(AMDGPU::SGPRRegBankID);
48   (void)RBSGPR;
49   assert(&RBSGPR == &AMDGPU::SGPRRegBank);
50
51   const RegisterBank &RBVGPR = getRegBank(AMDGPU::VGPRRegBankID);
52   (void)RBVGPR;
53   assert(&RBVGPR == &AMDGPU::VGPRRegBank);
54
55 }
56
57 unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &A,
58                                            const RegisterBank &B,
59                                            unsigned Size) const {
60   return RegisterBankInfo::copyCost(A, B, Size);
61 }
62
63 const RegisterBank &AMDGPURegisterBankInfo::getRegBankFromRegClass(
64     const TargetRegisterClass &RC) const {
65
66   if (TRI->isSGPRClass(&RC))
67     return getRegBank(AMDGPU::SGPRRegBankID);
68
69   return getRegBank(AMDGPU::VGPRRegBankID);
70 }
71
72 RegisterBankInfo::InstructionMappings
73 AMDGPURegisterBankInfo::getInstrAlternativeMappings(
74     const MachineInstr &MI) const {
75
76   const MachineFunction &MF = *MI.getParent()->getParent();
77   const MachineRegisterInfo &MRI = MF.getRegInfo();
78
79   unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
80
81   InstructionMappings AltMappings;
82   switch (MI.getOpcode()) {
83   case TargetOpcode::G_LOAD: {
84     // FIXME: Should we be hard coding the size for these mappings?
85     InstructionMapping SSMapping(1, 1,
86       getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
87                           AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
88       2); // Num Operands
89     AltMappings.emplace_back(std::move(SSMapping));
90
91     InstructionMapping VVMapping(2, 1,
92       getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
93                           AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
94       2); // Num Operands
95     AltMappings.emplace_back(std::move(VVMapping));
96
97     // FIXME: Should this be the pointer-size (64-bits) or the size of the
98     // register that will hold the bufffer resourc (128-bits).
99     InstructionMapping VSMapping(3, 1,
100       getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
101                           AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
102       2); // Num Operands
103     AltMappings.emplace_back(std::move(VSMapping));
104
105     return AltMappings;
106
107   }
108   default:
109     break;
110   }
111   return RegisterBankInfo::getInstrAlternativeMappings(MI);
112 }
113
114 void AMDGPURegisterBankInfo::applyMappingImpl(
115     const OperandsMapper &OpdMapper) const {
116   return applyDefaultMapping(OpdMapper);
117 }
118
119 static bool isInstrUniform(const MachineInstr &MI) {
120   if (!MI.hasOneMemOperand())
121     return false;
122
123   const MachineMemOperand *MMO = *MI.memoperands_begin();
124   return AMDGPU::isUniformMMO(MMO);
125 }
126
127 RegisterBankInfo::InstructionMapping
128 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
129
130   const MachineFunction &MF = *MI.getParent()->getParent();
131   const MachineRegisterInfo &MRI = MF.getRegInfo();
132   RegisterBankInfo::InstructionMapping Mapping =
133       InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
134   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
135   unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
136   unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
137
138   const ValueMapping *ValMapping;
139   const ValueMapping *PtrMapping;
140
141   if (isInstrUniform(MI)) {
142     // We have a uniform instruction so we want to use an SMRD load
143     ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
144     PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
145   } else {
146     ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
147     // FIXME: What would happen if we used SGPRRegBankID here?
148     PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
149   }
150
151   OpdsMapping[0] = ValMapping;
152   OpdsMapping[1] = PtrMapping;
153   Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
154   return Mapping;
155
156   // FIXME: Do we want to add a mapping for FLAT load, or should we just
157   // handle that during instruction selection?
158 }
159
160 RegisterBankInfo::InstructionMapping
161 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
162   RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
163
164   if (Mapping.isValid())
165     return Mapping;
166
167   const MachineFunction &MF = *MI.getParent()->getParent();
168   const MachineRegisterInfo &MRI = MF.getRegInfo();
169   Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
170   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
171
172   switch (MI.getOpcode()) {
173   default: break;
174   case AMDGPU::G_CONSTANT: {
175     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
176     OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
177     Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
178     return Mapping;
179   }
180   case AMDGPU::G_GEP: {
181     for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
182       if (!MI.getOperand(i).isReg())
183         continue;
184
185       unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
186       OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
187     }
188     Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
189     return Mapping;
190   }
191   case AMDGPU::G_STORE: {
192     assert(MI.getOperand(0).isReg());
193     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
194     // FIXME: We need to specify a different reg bank once scalar stores
195     // are supported.
196     const ValueMapping *ValMapping =
197         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
198     // FIXME: Depending on the type of store, the pointer could be in
199     // the SGPR Reg bank.
200     // FIXME: Pointer size should be based on the address space.
201     const ValueMapping *PtrMapping =
202         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
203
204     OpdsMapping[0] = ValMapping;
205     OpdsMapping[1] = PtrMapping;
206     Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
207     return Mapping;
208   }
209
210   case AMDGPU::G_LOAD:
211     return getInstrMappingForLoad(MI);
212   }
213
214   unsigned BankID = AMDGPU::SGPRRegBankID;
215
216   Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
217   unsigned Size = 0;
218   for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
219     // If the operand is not a register default to the size of the previous
220     // operand.
221     // FIXME: Can't we pull the types from the MachineInstr rather than the
222     // operands.
223     if (MI.getOperand(Idx).isReg())
224       Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
225     OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
226   }
227   Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
228
229   return Mapping;
230 }