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