1 //===- AMDGPUInstructionSelector --------------------------------*- 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 InstructionSelector class for 10 /// AMDGPU. 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H 14 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H 15 16 #include "AMDGPU.h" 17 #include "AMDGPUArgumentUsageInfo.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/CodeGen/Register.h" 21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 22 #include "llvm/IR/InstrTypes.h" 23 24 namespace { 25 #define GET_GLOBALISEL_PREDICATE_BITSET 26 #define AMDGPUSubtarget GCNSubtarget 27 #include "AMDGPUGenGlobalISel.inc" 28 #undef GET_GLOBALISEL_PREDICATE_BITSET 29 #undef AMDGPUSubtarget 30 } 31 32 namespace llvm { 33 34 namespace AMDGPU { 35 struct ImageDimIntrinsicInfo; 36 } 37 38 class AMDGPUInstrInfo; 39 class AMDGPURegisterBankInfo; 40 class GCNSubtarget; 41 class MachineInstr; 42 class MachineIRBuilder; 43 class MachineOperand; 44 class MachineRegisterInfo; 45 class RegisterBank; 46 class SIInstrInfo; 47 class SIMachineFunctionInfo; 48 class SIRegisterInfo; 49 50 class AMDGPUInstructionSelector : public InstructionSelector { 51 private: 52 MachineRegisterInfo *MRI; 53 54 public: 55 AMDGPUInstructionSelector(const GCNSubtarget &STI, 56 const AMDGPURegisterBankInfo &RBI, 57 const AMDGPUTargetMachine &TM); 58 59 bool select(MachineInstr &I) override; 60 static const char *getName(); 61 62 void setupMF(MachineFunction &MF, GISelKnownBits &KB, 63 CodeGenCoverage &CoverageInfo) override; 64 65 private: 66 struct GEPInfo { 67 const MachineInstr &GEP; 68 SmallVector<unsigned, 2> SgprParts; 69 SmallVector<unsigned, 2> VgprParts; 70 int64_t Imm; 71 GEPInfo(const MachineInstr &GEP) : GEP(GEP), Imm(0) { } 72 }; 73 74 bool isInstrUniform(const MachineInstr &MI) const; 75 bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const; 76 77 const RegisterBank *getArtifactRegBank( 78 Register Reg, const MachineRegisterInfo &MRI, 79 const TargetRegisterInfo &TRI) const; 80 81 /// tblgen-erated 'select' implementation. 82 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 83 84 MachineOperand getSubOperand64(MachineOperand &MO, 85 const TargetRegisterClass &SubRC, 86 unsigned SubIdx) const; 87 88 bool constrainCopyLikeIntrin(MachineInstr &MI, unsigned NewOpc) const; 89 bool selectCOPY(MachineInstr &I) const; 90 bool selectPHI(MachineInstr &I) const; 91 bool selectG_TRUNC(MachineInstr &I) const; 92 bool selectG_SZA_EXT(MachineInstr &I) const; 93 bool selectG_CONSTANT(MachineInstr &I) const; 94 bool selectG_FNEG(MachineInstr &I) const; 95 bool selectG_AND_OR_XOR(MachineInstr &I) const; 96 bool selectG_ADD_SUB(MachineInstr &I) const; 97 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const; 98 bool selectG_EXTRACT(MachineInstr &I) const; 99 bool selectG_MERGE_VALUES(MachineInstr &I) const; 100 bool selectG_UNMERGE_VALUES(MachineInstr &I) const; 101 bool selectG_BUILD_VECTOR_TRUNC(MachineInstr &I) const; 102 bool selectG_PTR_ADD(MachineInstr &I) const; 103 bool selectG_IMPLICIT_DEF(MachineInstr &I) const; 104 bool selectG_INSERT(MachineInstr &I) const; 105 106 bool selectInterpP1F16(MachineInstr &MI) const; 107 bool selectG_INTRINSIC(MachineInstr &I) const; 108 109 bool selectEndCfIntrinsic(MachineInstr &MI) const; 110 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 111 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 112 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const; 113 114 bool selectImageIntrinsic(MachineInstr &MI, 115 const AMDGPU::ImageDimIntrinsicInfo *Intr) const; 116 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const; 117 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const; 118 bool selectG_ICMP(MachineInstr &I) const; 119 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const; 120 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI, 121 SmallVectorImpl<GEPInfo> &AddrInfo) const; 122 bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const; 123 124 void initM0(MachineInstr &I) const; 125 bool selectG_LOAD_ATOMICRMW(MachineInstr &I) const; 126 bool selectG_AMDGPU_ATOMIC_CMPXCHG(MachineInstr &I) const; 127 bool selectG_STORE(MachineInstr &I) const; 128 bool selectG_SELECT(MachineInstr &I) const; 129 bool selectG_BRCOND(MachineInstr &I) const; 130 bool selectG_FRAME_INDEX_GLOBAL_VALUE(MachineInstr &I) const; 131 bool selectG_PTR_MASK(MachineInstr &I) const; 132 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const; 133 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const; 134 bool selectG_SHUFFLE_VECTOR(MachineInstr &I) const; 135 136 std::pair<Register, unsigned> 137 selectVOP3ModsImpl(MachineOperand &Root) const; 138 139 InstructionSelector::ComplexRendererFns 140 selectVCSRC(MachineOperand &Root) const; 141 142 InstructionSelector::ComplexRendererFns 143 selectVSRC0(MachineOperand &Root) const; 144 145 InstructionSelector::ComplexRendererFns 146 selectVOP3Mods0(MachineOperand &Root) const; 147 InstructionSelector::ComplexRendererFns 148 selectVOP3OMods(MachineOperand &Root) const; 149 InstructionSelector::ComplexRendererFns 150 selectVOP3Mods(MachineOperand &Root) const; 151 152 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const; 153 154 InstructionSelector::ComplexRendererFns 155 selectVOP3Mods_nnan(MachineOperand &Root) const; 156 157 std::pair<Register, unsigned> 158 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI) const; 159 160 InstructionSelector::ComplexRendererFns 161 selectVOP3PMods(MachineOperand &Root) const; 162 163 InstructionSelector::ComplexRendererFns 164 selectVOP3OpSelMods(MachineOperand &Root) const; 165 166 InstructionSelector::ComplexRendererFns 167 selectSmrdImm(MachineOperand &Root) const; 168 InstructionSelector::ComplexRendererFns 169 selectSmrdImm32(MachineOperand &Root) const; 170 InstructionSelector::ComplexRendererFns 171 selectSmrdSgpr(MachineOperand &Root) const; 172 173 template <bool Signed> 174 InstructionSelector::ComplexRendererFns 175 selectFlatOffsetImpl(MachineOperand &Root) const; 176 InstructionSelector::ComplexRendererFns 177 selectFlatOffset(MachineOperand &Root) const; 178 179 InstructionSelector::ComplexRendererFns 180 selectFlatOffsetSigned(MachineOperand &Root) const; 181 182 InstructionSelector::ComplexRendererFns 183 selectMUBUFScratchOffen(MachineOperand &Root) const; 184 InstructionSelector::ComplexRendererFns 185 selectMUBUFScratchOffset(MachineOperand &Root) const; 186 187 bool isDSOffsetLegal(Register Base, int64_t Offset, 188 unsigned OffsetBits) const; 189 190 std::pair<Register, unsigned> 191 selectDS1Addr1OffsetImpl(MachineOperand &Root) const; 192 InstructionSelector::ComplexRendererFns 193 selectDS1Addr1Offset(MachineOperand &Root) const; 194 195 std::pair<Register, unsigned> 196 selectDS64Bit4ByteAlignedImpl(MachineOperand &Root) const; 197 InstructionSelector::ComplexRendererFns 198 selectDS64Bit4ByteAligned(MachineOperand &Root) const; 199 200 std::pair<Register, int64_t> 201 getPtrBaseWithConstantOffset(Register Root, 202 const MachineRegisterInfo &MRI) const; 203 204 // Parse out a chain of up to two g_ptr_add instructions. 205 // g_ptr_add (n0, _) 206 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3)) 207 struct MUBUFAddressData { 208 Register N0, N2, N3; 209 int64_t Offset = 0; 210 }; 211 212 bool shouldUseAddr64(MUBUFAddressData AddrData) const; 213 214 void splitIllegalMUBUFOffset(MachineIRBuilder &B, 215 Register &SOffset, int64_t &ImmOffset) const; 216 217 MUBUFAddressData parseMUBUFAddress(Register Src) const; 218 219 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr, 220 Register &RSrcReg, Register &SOffset, 221 int64_t &Offset) const; 222 223 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg, 224 Register &SOffset, int64_t &Offset) const; 225 226 InstructionSelector::ComplexRendererFns 227 selectMUBUFAddr64(MachineOperand &Root) const; 228 229 InstructionSelector::ComplexRendererFns 230 selectMUBUFOffset(MachineOperand &Root) const; 231 232 InstructionSelector::ComplexRendererFns 233 selectMUBUFOffsetAtomic(MachineOperand &Root) const; 234 235 InstructionSelector::ComplexRendererFns 236 selectMUBUFAddr64Atomic(MachineOperand &Root) const; 237 238 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const; 239 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const; 240 241 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 242 int OpIdx = -1) const; 243 244 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 245 int OpIdx) const; 246 247 void renderTruncTImm1(MachineInstrBuilder &MIB, const MachineInstr &MI, 248 int OpIdx) const { 249 renderTruncTImm(MIB, MI, OpIdx); 250 } 251 252 void renderTruncTImm8(MachineInstrBuilder &MIB, const MachineInstr &MI, 253 int OpIdx) const { 254 renderTruncTImm(MIB, MI, OpIdx); 255 } 256 257 void renderTruncTImm16(MachineInstrBuilder &MIB, const MachineInstr &MI, 258 int OpIdx) const { 259 renderTruncTImm(MIB, MI, OpIdx); 260 } 261 262 void renderTruncTImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 263 int OpIdx) const { 264 renderTruncTImm(MIB, MI, OpIdx); 265 } 266 267 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 268 int OpIdx) const; 269 270 void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 271 int OpIdx) const; 272 273 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 274 int OpIdx) const; 275 void renderExtractGLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 276 int OpIdx) const; 277 void renderExtractSLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 278 int OpIdx) const; 279 void renderExtractDLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 280 int OpIdx) const; 281 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI, 282 int OpIdx) const; 283 284 bool isInlineImmediate16(int64_t Imm) const; 285 bool isInlineImmediate32(int64_t Imm) const; 286 bool isInlineImmediate64(int64_t Imm) const; 287 bool isInlineImmediate(const APFloat &Imm) const; 288 289 const SIInstrInfo &TII; 290 const SIRegisterInfo &TRI; 291 const AMDGPURegisterBankInfo &RBI; 292 const AMDGPUTargetMachine &TM; 293 const GCNSubtarget &STI; 294 bool EnableLateStructurizeCFG; 295 #define GET_GLOBALISEL_PREDICATES_DECL 296 #define AMDGPUSubtarget GCNSubtarget 297 #include "AMDGPUGenGlobalISel.inc" 298 #undef GET_GLOBALISEL_PREDICATES_DECL 299 #undef AMDGPUSubtarget 300 301 #define GET_GLOBALISEL_TEMPORARIES_DECL 302 #include "AMDGPUGenGlobalISel.inc" 303 #undef GET_GLOBALISEL_TEMPORARIES_DECL 304 }; 305 306 } // End llvm namespace. 307 #endif 308