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