]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304659, 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     const InstructionMapping &SSMapping = getInstructionMapping(
86         1, 1, getOperandsMapping(
87                   {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
88                    AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
89         2); // Num Operands
90     AltMappings.push_back(&SSMapping);
91
92     const InstructionMapping &VVMapping = getInstructionMapping(
93         2, 1, getOperandsMapping(
94                   {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
95                    AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
96         2); // Num Operands
97     AltMappings.push_back(&VVMapping);
98
99     // FIXME: Should this be the pointer-size (64-bits) or the size of the
100     // register that will hold the bufffer resourc (128-bits).
101     const InstructionMapping &VSMapping = getInstructionMapping(
102         3, 1, getOperandsMapping(
103                   {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
104                    AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
105         2); // Num Operands
106     AltMappings.push_back(&VSMapping);
107
108     return AltMappings;
109
110   }
111   default:
112     break;
113   }
114   return RegisterBankInfo::getInstrAlternativeMappings(MI);
115 }
116
117 void AMDGPURegisterBankInfo::applyMappingImpl(
118     const OperandsMapper &OpdMapper) const {
119   return applyDefaultMapping(OpdMapper);
120 }
121
122 static bool isInstrUniform(const MachineInstr &MI) {
123   if (!MI.hasOneMemOperand())
124     return false;
125
126   const MachineMemOperand *MMO = *MI.memoperands_begin();
127   return AMDGPU::isUniformMMO(MMO);
128 }
129
130 const RegisterBankInfo::InstructionMapping &
131 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
132
133   const MachineFunction &MF = *MI.getParent()->getParent();
134   const MachineRegisterInfo &MRI = MF.getRegInfo();
135   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
136   unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
137   unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
138
139   const ValueMapping *ValMapping;
140   const ValueMapping *PtrMapping;
141
142   if (isInstrUniform(MI)) {
143     // We have a uniform instruction so we want to use an SMRD load
144     ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
145     PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
146   } else {
147     ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
148     // FIXME: What would happen if we used SGPRRegBankID here?
149     PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
150   }
151
152   OpdsMapping[0] = ValMapping;
153   OpdsMapping[1] = PtrMapping;
154   const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
155       1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
156   return Mapping;
157
158   // FIXME: Do we want to add a mapping for FLAT load, or should we just
159   // handle that during instruction selection?
160 }
161
162 const RegisterBankInfo::InstructionMapping &
163 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
164   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
165
166   if (Mapping.isValid())
167     return Mapping;
168
169   const MachineFunction &MF = *MI.getParent()->getParent();
170   const MachineRegisterInfo &MRI = MF.getRegInfo();
171   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
172
173   bool IsComplete = true;
174   switch (MI.getOpcode()) {
175   default:
176     IsComplete = false;
177     break;
178   case AMDGPU::G_CONSTANT: {
179     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
180     OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
181     break;
182   }
183   case AMDGPU::G_GEP: {
184     for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
185       if (!MI.getOperand(i).isReg())
186         continue;
187
188       unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
189       OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
190     }
191     break;
192   }
193   case AMDGPU::G_STORE: {
194     assert(MI.getOperand(0).isReg());
195     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
196     // FIXME: We need to specify a different reg bank once scalar stores
197     // are supported.
198     const ValueMapping *ValMapping =
199         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
200     // FIXME: Depending on the type of store, the pointer could be in
201     // the SGPR Reg bank.
202     // FIXME: Pointer size should be based on the address space.
203     const ValueMapping *PtrMapping =
204         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
205
206     OpdsMapping[0] = ValMapping;
207     OpdsMapping[1] = PtrMapping;
208     break;
209   }
210
211   case AMDGPU::G_LOAD:
212     return getInstrMappingForLoad(MI);
213   }
214
215   if (!IsComplete) {
216     unsigned BankID = AMDGPU::SGPRRegBankID;
217
218     unsigned Size = 0;
219     for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
220       // If the operand is not a register default to the size of the previous
221       // operand.
222       // FIXME: Can't we pull the types from the MachineInstr rather than the
223       // operands.
224       if (MI.getOperand(Idx).isReg())
225         Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
226       OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
227     }
228   }
229   return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
230                                MI.getNumOperands());
231 }