1 | //===- AMDGPURegisterBankInfo -----------------------------------*- C++ -*-==// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// \file |
9 | /// This file declares the targeting of the RegisterBankInfo class for AMDGPU. |
10 | /// \todo This should be generated by TableGen. |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUREGISTERBANKINFO_H |
14 | #define LLVM_LIB_TARGET_AMDGPU_AMDGPUREGISTERBANKINFO_H |
15 | |
16 | #include "llvm/ADT/SmallSet.h" |
17 | #include "llvm/CodeGen/MachineBasicBlock.h" |
18 | #include "llvm/CodeGen/Register.h" |
19 | #include "llvm/CodeGen/RegisterBankInfo.h" |
20 | |
21 | #define GET_REGBANK_DECLARATIONS |
22 | #include "AMDGPUGenRegisterBank.inc" |
23 | |
24 | namespace llvm { |
25 | |
26 | class LLT; |
27 | class GCNSubtarget; |
28 | class MachineIRBuilder; |
29 | class SIInstrInfo; |
30 | class SIRegisterInfo; |
31 | class TargetRegisterInfo; |
32 | |
33 | /// This class provides the information for the target register banks. |
34 | class AMDGPUGenRegisterBankInfo : public RegisterBankInfo { |
35 | |
36 | protected: |
37 | |
38 | #define GET_TARGET_REGBANK_CLASS |
39 | #include "AMDGPUGenRegisterBank.inc" |
40 | }; |
41 | |
42 | class AMDGPURegisterBankInfo final : public AMDGPUGenRegisterBankInfo { |
43 | public: |
44 | const GCNSubtarget &Subtarget; |
45 | const SIRegisterInfo *TRI; |
46 | const SIInstrInfo *TII; |
47 | |
48 | bool buildVCopy(MachineIRBuilder &B, Register DstReg, Register SrcReg) const; |
49 | |
50 | bool collectWaterfallOperands( |
51 | SmallSet<Register, 4> &SGPROperandRegs, |
52 | MachineInstr &MI, |
53 | MachineRegisterInfo &MRI, |
54 | ArrayRef<unsigned> OpIndices) const; |
55 | |
56 | bool executeInWaterfallLoop(MachineIRBuilder &B, |
57 | iterator_range<MachineBasicBlock::iterator> Range, |
58 | SmallSet<Register, 4> &SGPROperandRegs) const; |
59 | |
60 | Register buildReadFirstLane(MachineIRBuilder &B, MachineRegisterInfo &MRI, |
61 | Register Src) const; |
62 | |
63 | bool executeInWaterfallLoop(MachineIRBuilder &B, MachineInstr &MI, |
64 | ArrayRef<unsigned> OpIndices) const; |
65 | |
66 | void constrainOpWithReadfirstlane(MachineIRBuilder &B, MachineInstr &MI, |
67 | unsigned OpIdx) const; |
68 | bool applyMappingDynStackAlloc(MachineIRBuilder &B, |
69 | const OperandsMapper &OpdMapper, |
70 | MachineInstr &MI) const; |
71 | bool applyMappingLoad(MachineIRBuilder &B, const OperandsMapper &OpdMapper, |
72 | MachineInstr &MI) const; |
73 | bool applyMappingImage(MachineIRBuilder &B, MachineInstr &MI, |
74 | const OperandsMapper &OpdMapper, int RSrcIdx) const; |
75 | unsigned setBufferOffsets(MachineIRBuilder &B, Register CombinedOffset, |
76 | Register &VOffsetReg, Register &SOffsetReg, |
77 | int64_t &InstOffsetVal, Align Alignment) const; |
78 | bool applyMappingSBufferLoad(MachineIRBuilder &B, |
79 | const OperandsMapper &OpdMapper) const; |
80 | |
81 | bool applyMappingBFE(MachineIRBuilder &B, const OperandsMapper &OpdMapper, |
82 | bool Signed) const; |
83 | |
84 | bool applyMappingMAD_64_32(MachineIRBuilder &B, |
85 | const OperandsMapper &OpdMapper) const; |
86 | |
87 | void applyMappingSMULU64(MachineIRBuilder &B, |
88 | const OperandsMapper &OpdMapper) const; |
89 | |
90 | Register handleD16VData(MachineIRBuilder &B, MachineRegisterInfo &MRI, |
91 | Register Reg) const; |
92 | |
93 | std::pair<Register, unsigned> |
94 | splitBufferOffsets(MachineIRBuilder &B, Register Offset) const; |
95 | |
96 | /// See RegisterBankInfo::applyMapping. |
97 | void applyMappingImpl(MachineIRBuilder &Builder, |
98 | const OperandsMapper &OpdMapper) const override; |
99 | |
100 | const ValueMapping *getValueMappingForPtr(const MachineRegisterInfo &MRI, |
101 | Register Ptr) const; |
102 | |
103 | const RegisterBankInfo::InstructionMapping & |
104 | getInstrMappingForLoad(const MachineInstr &MI) const; |
105 | |
106 | unsigned getRegBankID(Register Reg, const MachineRegisterInfo &MRI, |
107 | unsigned Default = AMDGPU::VGPRRegBankID) const; |
108 | |
109 | // Return a value mapping for an operand that is required to be an SGPR. |
110 | const ValueMapping *getSGPROpMapping(Register Reg, |
111 | const MachineRegisterInfo &MRI, |
112 | const TargetRegisterInfo &TRI) const; |
113 | |
114 | // Return a value mapping for an operand that is required to be a VGPR. |
115 | const ValueMapping *getVGPROpMapping(Register Reg, |
116 | const MachineRegisterInfo &MRI, |
117 | const TargetRegisterInfo &TRI) const; |
118 | |
119 | // Return a value mapping for an operand that is required to be a AGPR. |
120 | const ValueMapping *getAGPROpMapping(Register Reg, |
121 | const MachineRegisterInfo &MRI, |
122 | const TargetRegisterInfo &TRI) const; |
123 | |
124 | /// Split 64-bit value \p Reg into two 32-bit halves and populate them into \p |
125 | /// Regs. This appropriately sets the regbank of the new registers. |
126 | void split64BitValueForMapping(MachineIRBuilder &B, |
127 | SmallVector<Register, 2> &Regs, |
128 | LLT HalfTy, |
129 | Register Reg) const; |
130 | |
131 | template <unsigned NumOps> |
132 | struct OpRegBankEntry { |
133 | int8_t RegBanks[NumOps]; |
134 | int16_t Cost; |
135 | }; |
136 | |
137 | template <unsigned NumOps> |
138 | InstructionMappings |
139 | addMappingFromTable(const MachineInstr &MI, const MachineRegisterInfo &MRI, |
140 | const std::array<unsigned, NumOps> RegSrcOpIdx, |
141 | ArrayRef<OpRegBankEntry<NumOps>> Table) const; |
142 | |
143 | RegisterBankInfo::InstructionMappings |
144 | getInstrAlternativeMappingsIntrinsic( |
145 | const MachineInstr &MI, const MachineRegisterInfo &MRI) const; |
146 | |
147 | RegisterBankInfo::InstructionMappings |
148 | getInstrAlternativeMappingsIntrinsicWSideEffects( |
149 | const MachineInstr &MI, const MachineRegisterInfo &MRI) const; |
150 | |
151 | unsigned getMappingType(const MachineRegisterInfo &MRI, |
152 | const MachineInstr &MI) const; |
153 | |
154 | bool isSALUMapping(const MachineInstr &MI) const; |
155 | |
156 | const InstructionMapping &getDefaultMappingSOP(const MachineInstr &MI) const; |
157 | const InstructionMapping &getDefaultMappingVOP(const MachineInstr &MI) const; |
158 | const InstructionMapping &getDefaultMappingAllVGPR( |
159 | const MachineInstr &MI) const; |
160 | |
161 | const InstructionMapping &getImageMapping(const MachineRegisterInfo &MRI, |
162 | const MachineInstr &MI, |
163 | int RsrcIdx) const; |
164 | |
165 | public: |
166 | AMDGPURegisterBankInfo(const GCNSubtarget &STI); |
167 | |
168 | bool isDivergentRegBank(const RegisterBank *RB) const override; |
169 | |
170 | unsigned copyCost(const RegisterBank &A, const RegisterBank &B, |
171 | TypeSize Size) const override; |
172 | |
173 | unsigned getBreakDownCost(const ValueMapping &ValMapping, |
174 | const RegisterBank *CurBank = nullptr) const override; |
175 | |
176 | const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, |
177 | LLT) const override; |
178 | |
179 | bool isScalarLoadLegal(const MachineInstr &MI) const; |
180 | |
181 | InstructionMappings |
182 | getInstrAlternativeMappings(const MachineInstr &MI) const override; |
183 | |
184 | const InstructionMapping & |
185 | getInstrMapping(const MachineInstr &MI) const override; |
186 | |
187 | private: |
188 | bool foldExtractEltToCmpSelect(MachineIRBuilder &B, MachineInstr &MI, |
189 | const OperandsMapper &OpdMapper) const; |
190 | bool foldInsertEltToCmpSelect(MachineIRBuilder &B, MachineInstr &MI, |
191 | const OperandsMapper &OpdMapper) const; |
192 | }; |
193 | } // End llvm namespace. |
194 | #endif |
195 | |