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