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 24namespace { 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 32namespace llvm { 33 34namespace AMDGPU { 35struct ImageDimIntrinsicInfo; 36} 37 38class AMDGPUInstrInfo; 39class AMDGPURegisterBankInfo; 40class GCNSubtarget; 41class MachineInstr; 42class MachineIRBuilder; 43class MachineOperand; 44class MachineRegisterInfo; 45class RegisterBank; 46class SIInstrInfo; 47class SIMachineFunctionInfo; 48class SIRegisterInfo; 49 50class AMDGPUInstructionSelector : public InstructionSelector { 51private: 52 MachineRegisterInfo *MRI; 53 54public: 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 65private: 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_FABS(MachineInstr &I) const; 96 bool selectG_AND_OR_XOR(MachineInstr &I) const; 97 bool selectG_ADD_SUB(MachineInstr &I) const; 98 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const; 99 bool selectG_EXTRACT(MachineInstr &I) const; 100 bool selectG_MERGE_VALUES(MachineInstr &I) const; 101 bool selectG_UNMERGE_VALUES(MachineInstr &I) const; 102 bool selectG_BUILD_VECTOR_TRUNC(MachineInstr &I) const; 103 bool selectG_PTR_ADD(MachineInstr &I) const; 104 bool selectG_IMPLICIT_DEF(MachineInstr &I) const; 105 bool selectG_INSERT(MachineInstr &I) const; 106 107 bool selectInterpP1F16(MachineInstr &MI) const; 108 bool selectDivScale(MachineInstr &MI) const; 109 bool selectIntrinsicIcmp(MachineInstr &MI) const; 110 bool selectBallot(MachineInstr &I) const; 111 bool selectG_INTRINSIC(MachineInstr &I) const; 112 113 bool selectEndCfIntrinsic(MachineInstr &MI) const; 114 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 115 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 116 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const; 117 118 bool selectImageIntrinsic(MachineInstr &MI, 119 const AMDGPU::ImageDimIntrinsicInfo *Intr) const; 120 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const; 121 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const; 122 bool selectG_ICMP(MachineInstr &I) const; 123 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const; 124 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI, 125 SmallVectorImpl<GEPInfo> &AddrInfo) const; 126 bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const; 127 128 void initM0(MachineInstr &I) const; 129 bool selectG_LOAD_ATOMICRMW(MachineInstr &I) const; 130 bool selectG_AMDGPU_ATOMIC_CMPXCHG(MachineInstr &I) const; 131 bool selectG_STORE(MachineInstr &I) const; 132 bool selectG_SELECT(MachineInstr &I) const; 133 bool selectG_BRCOND(MachineInstr &I) const; 134 bool selectG_FRAME_INDEX_GLOBAL_VALUE(MachineInstr &I) const; 135 bool selectG_PTRMASK(MachineInstr &I) const; 136 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const; 137 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const; 138 bool selectG_SHUFFLE_VECTOR(MachineInstr &I) const; 139 140 std::pair<Register, unsigned> 141 selectVOP3ModsImpl(MachineOperand &Root) const; 142 143 InstructionSelector::ComplexRendererFns 144 selectVCSRC(MachineOperand &Root) const; 145 146 InstructionSelector::ComplexRendererFns 147 selectVSRC0(MachineOperand &Root) const; 148 149 InstructionSelector::ComplexRendererFns 150 selectVOP3Mods0(MachineOperand &Root) const; 151 InstructionSelector::ComplexRendererFns 152 selectVOP3OMods(MachineOperand &Root) const; 153 InstructionSelector::ComplexRendererFns 154 selectVOP3Mods(MachineOperand &Root) const; 155 156 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const; 157 158 InstructionSelector::ComplexRendererFns 159 selectVOP3Mods_nnan(MachineOperand &Root) const; 160 161 std::pair<Register, unsigned> 162 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI) const; 163 164 InstructionSelector::ComplexRendererFns 165 selectVOP3PMods(MachineOperand &Root) const; 166 167 InstructionSelector::ComplexRendererFns 168 selectVOP3OpSelMods(MachineOperand &Root) const; 169 170 InstructionSelector::ComplexRendererFns 171 selectSmrdImm(MachineOperand &Root) const; 172 InstructionSelector::ComplexRendererFns 173 selectSmrdImm32(MachineOperand &Root) const; 174 InstructionSelector::ComplexRendererFns 175 selectSmrdSgpr(MachineOperand &Root) const; 176 177 template <bool Signed> 178 InstructionSelector::ComplexRendererFns 179 selectFlatOffsetImpl(MachineOperand &Root) const; 180 InstructionSelector::ComplexRendererFns 181 selectFlatOffset(MachineOperand &Root) const; 182 183 InstructionSelector::ComplexRendererFns 184 selectFlatOffsetSigned(MachineOperand &Root) const; 185 186 InstructionSelector::ComplexRendererFns 187 selectMUBUFScratchOffen(MachineOperand &Root) const; 188 InstructionSelector::ComplexRendererFns 189 selectMUBUFScratchOffset(MachineOperand &Root) const; 190 191 bool isDSOffsetLegal(Register Base, int64_t Offset, 192 unsigned OffsetBits) const; 193 194 std::pair<Register, unsigned> 195 selectDS1Addr1OffsetImpl(MachineOperand &Root) const; 196 InstructionSelector::ComplexRendererFns 197 selectDS1Addr1Offset(MachineOperand &Root) const; 198 199 std::pair<Register, unsigned> 200 selectDS64Bit4ByteAlignedImpl(MachineOperand &Root) const; 201 InstructionSelector::ComplexRendererFns 202 selectDS64Bit4ByteAligned(MachineOperand &Root) const; 203 204 std::pair<Register, int64_t> 205 getPtrBaseWithConstantOffset(Register Root, 206 const MachineRegisterInfo &MRI) const; 207 208 // Parse out a chain of up to two g_ptr_add instructions. 209 // g_ptr_add (n0, _) 210 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3)) 211 struct MUBUFAddressData { 212 Register N0, N2, N3; 213 int64_t Offset = 0; 214 }; 215 216 bool shouldUseAddr64(MUBUFAddressData AddrData) const; 217 218 void splitIllegalMUBUFOffset(MachineIRBuilder &B, 219 Register &SOffset, int64_t &ImmOffset) const; 220 221 MUBUFAddressData parseMUBUFAddress(Register Src) const; 222 223 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr, 224 Register &RSrcReg, Register &SOffset, 225 int64_t &Offset) const; 226 227 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg, 228 Register &SOffset, int64_t &Offset) const; 229 230 InstructionSelector::ComplexRendererFns 231 selectMUBUFAddr64(MachineOperand &Root) const; 232 233 InstructionSelector::ComplexRendererFns 234 selectMUBUFOffset(MachineOperand &Root) const; 235 236 InstructionSelector::ComplexRendererFns 237 selectMUBUFOffsetAtomic(MachineOperand &Root) const; 238 239 InstructionSelector::ComplexRendererFns 240 selectMUBUFAddr64Atomic(MachineOperand &Root) const; 241 242 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const; 243 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const; 244 245 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 246 int OpIdx = -1) const; 247 248 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 249 int OpIdx) const; 250 251 void renderTruncTImm1(MachineInstrBuilder &MIB, const MachineInstr &MI, 252 int OpIdx) const { 253 renderTruncTImm(MIB, MI, OpIdx); 254 } 255 256 void renderTruncTImm8(MachineInstrBuilder &MIB, const MachineInstr &MI, 257 int OpIdx) const { 258 renderTruncTImm(MIB, MI, OpIdx); 259 } 260 261 void renderTruncTImm16(MachineInstrBuilder &MIB, const MachineInstr &MI, 262 int OpIdx) const { 263 renderTruncTImm(MIB, MI, OpIdx); 264 } 265 266 void renderTruncTImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 267 int OpIdx) const { 268 renderTruncTImm(MIB, MI, OpIdx); 269 } 270 271 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 272 int OpIdx) const; 273 274 void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 275 int OpIdx) const; 276 277 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 278 int OpIdx) const; 279 void renderExtractGLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 280 int OpIdx) const; 281 void renderExtractSLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 282 int OpIdx) const; 283 void renderExtractDLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 284 int OpIdx) const; 285 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI, 286 int OpIdx) const; 287 288 bool isInlineImmediate16(int64_t Imm) const; 289 bool isInlineImmediate32(int64_t Imm) const; 290 bool isInlineImmediate64(int64_t Imm) const; 291 bool isInlineImmediate(const APFloat &Imm) const; 292 293 const SIInstrInfo &TII; 294 const SIRegisterInfo &TRI; 295 const AMDGPURegisterBankInfo &RBI; 296 const AMDGPUTargetMachine &TM; 297 const GCNSubtarget &STI; 298 bool EnableLateStructurizeCFG; 299#define GET_GLOBALISEL_PREDICATES_DECL 300#define AMDGPUSubtarget GCNSubtarget 301#include "AMDGPUGenGlobalISel.inc" 302#undef GET_GLOBALISEL_PREDICATES_DECL 303#undef AMDGPUSubtarget 304 305#define GET_GLOBALISEL_TEMPORARIES_DECL 306#include "AMDGPUGenGlobalISel.inc" 307#undef GET_GLOBALISEL_TEMPORARIES_DECL 308}; 309 310} // End llvm namespace. 311#endif 312