1*700637cbSDimitry Andric //===- AMDGPURegBankLegalizeHelper ------------------------------*- C++ -*-===// 2*700637cbSDimitry Andric // 3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*700637cbSDimitry Andric // 7*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 8*700637cbSDimitry Andric 9*700637cbSDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZEHELPER_H 10*700637cbSDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZEHELPER_H 11*700637cbSDimitry Andric 12*700637cbSDimitry Andric #include "AMDGPURegBankLegalizeRules.h" 13*700637cbSDimitry Andric #include "llvm/ADT/SmallSet.h" 14*700637cbSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 15*700637cbSDimitry Andric 16*700637cbSDimitry Andric namespace llvm { 17*700637cbSDimitry Andric 18*700637cbSDimitry Andric class MachineIRBuilder; 19*700637cbSDimitry Andric 20*700637cbSDimitry Andric namespace AMDGPU { 21*700637cbSDimitry Andric 22*700637cbSDimitry Andric // Receives list of RegBankLLTMappingApplyID and applies register banks on all 23*700637cbSDimitry Andric // operands. It is user's responsibility to provide RegBankLLTMappingApplyIDs 24*700637cbSDimitry Andric // for all register operands, there is no need to specify NonReg for trailing 25*700637cbSDimitry Andric // imm operands. This finishes selection of register banks if there is no need 26*700637cbSDimitry Andric // to replace instruction. In other case InstApplyMethod will create new 27*700637cbSDimitry Andric // instruction(s). 28*700637cbSDimitry Andric class RegBankLegalizeHelper { 29*700637cbSDimitry Andric const GCNSubtarget &ST; 30*700637cbSDimitry Andric MachineIRBuilder &B; 31*700637cbSDimitry Andric MachineRegisterInfo &MRI; 32*700637cbSDimitry Andric const MachineUniformityInfo &MUI; 33*700637cbSDimitry Andric const RegisterBankInfo &RBI; 34*700637cbSDimitry Andric const RegBankLegalizeRules &RBLRules; 35*700637cbSDimitry Andric const RegisterBank *SgprRB; 36*700637cbSDimitry Andric const RegisterBank *VgprRB; 37*700637cbSDimitry Andric const RegisterBank *VccRB; 38*700637cbSDimitry Andric 39*700637cbSDimitry Andric static constexpr LLT S1 = LLT::scalar(1); 40*700637cbSDimitry Andric static constexpr LLT S16 = LLT::scalar(16); 41*700637cbSDimitry Andric static constexpr LLT S32 = LLT::scalar(32); 42*700637cbSDimitry Andric static constexpr LLT S64 = LLT::scalar(64); 43*700637cbSDimitry Andric static constexpr LLT S96 = LLT::scalar(96); 44*700637cbSDimitry Andric static constexpr LLT S128 = LLT::scalar(128); 45*700637cbSDimitry Andric static constexpr LLT S256 = LLT::scalar(256); 46*700637cbSDimitry Andric 47*700637cbSDimitry Andric static constexpr LLT V2S16 = LLT::fixed_vector(2, 16); 48*700637cbSDimitry Andric static constexpr LLT V4S16 = LLT::fixed_vector(4, 16); 49*700637cbSDimitry Andric static constexpr LLT V6S16 = LLT::fixed_vector(6, 16); 50*700637cbSDimitry Andric static constexpr LLT V8S16 = LLT::fixed_vector(8, 16); 51*700637cbSDimitry Andric static constexpr LLT V16S16 = LLT::fixed_vector(16, 16); 52*700637cbSDimitry Andric static constexpr LLT V32S16 = LLT::fixed_vector(32, 16); 53*700637cbSDimitry Andric 54*700637cbSDimitry Andric static constexpr LLT V2S32 = LLT::fixed_vector(2, 32); 55*700637cbSDimitry Andric static constexpr LLT V3S32 = LLT::fixed_vector(3, 32); 56*700637cbSDimitry Andric static constexpr LLT V4S32 = LLT::fixed_vector(4, 32); 57*700637cbSDimitry Andric static constexpr LLT V6S32 = LLT::fixed_vector(6, 32); 58*700637cbSDimitry Andric static constexpr LLT V7S32 = LLT::fixed_vector(7, 32); 59*700637cbSDimitry Andric static constexpr LLT V8S32 = LLT::fixed_vector(8, 32); 60*700637cbSDimitry Andric static constexpr LLT V16S32 = LLT::fixed_vector(16, 32); 61*700637cbSDimitry Andric 62*700637cbSDimitry Andric static constexpr LLT V2S64 = LLT::fixed_vector(2, 64); 63*700637cbSDimitry Andric static constexpr LLT V3S64 = LLT::fixed_vector(3, 64); 64*700637cbSDimitry Andric static constexpr LLT V4S64 = LLT::fixed_vector(4, 64); 65*700637cbSDimitry Andric static constexpr LLT V8S64 = LLT::fixed_vector(8, 64); 66*700637cbSDimitry Andric static constexpr LLT V16S64 = LLT::fixed_vector(16, 64); 67*700637cbSDimitry Andric 68*700637cbSDimitry Andric static constexpr LLT P1 = LLT::pointer(1, 64); 69*700637cbSDimitry Andric static constexpr LLT P4 = LLT::pointer(4, 64); 70*700637cbSDimitry Andric static constexpr LLT P6 = LLT::pointer(6, 32); 71*700637cbSDimitry Andric 72*700637cbSDimitry Andric MachineRegisterInfo::VRegAttrs SgprRB_S32 = {SgprRB, S32}; 73*700637cbSDimitry Andric MachineRegisterInfo::VRegAttrs VgprRB_S32 = {VgprRB, S32}; 74*700637cbSDimitry Andric MachineRegisterInfo::VRegAttrs VccRB_S1 = {VccRB, S1}; 75*700637cbSDimitry Andric 76*700637cbSDimitry Andric public: 77*700637cbSDimitry Andric RegBankLegalizeHelper(MachineIRBuilder &B, const MachineUniformityInfo &MUI, 78*700637cbSDimitry Andric const RegisterBankInfo &RBI, 79*700637cbSDimitry Andric const RegBankLegalizeRules &RBLRules); 80*700637cbSDimitry Andric 81*700637cbSDimitry Andric void findRuleAndApplyMapping(MachineInstr &MI); 82*700637cbSDimitry Andric 83*700637cbSDimitry Andric // Manual apply helpers. 84*700637cbSDimitry Andric void applyMappingPHI(MachineInstr &MI); 85*700637cbSDimitry Andric void applyMappingTrivial(MachineInstr &MI); 86*700637cbSDimitry Andric 87*700637cbSDimitry Andric private: 88*700637cbSDimitry Andric bool executeInWaterfallLoop(MachineIRBuilder &B, 89*700637cbSDimitry Andric iterator_range<MachineBasicBlock::iterator> Range, 90*700637cbSDimitry Andric SmallSet<Register, 4> &SgprOperandRegs); 91*700637cbSDimitry Andric 92*700637cbSDimitry Andric LLT getTyFromID(RegBankLLTMappingApplyID ID); 93*700637cbSDimitry Andric LLT getBTyFromID(RegBankLLTMappingApplyID ID, LLT Ty); 94*700637cbSDimitry Andric 95*700637cbSDimitry Andric const RegisterBank *getRegBankFromID(RegBankLLTMappingApplyID ID); 96*700637cbSDimitry Andric 97*700637cbSDimitry Andric void 98*700637cbSDimitry Andric applyMappingDst(MachineInstr &MI, unsigned &OpIdx, 99*700637cbSDimitry Andric const SmallVectorImpl<RegBankLLTMappingApplyID> &MethodIDs); 100*700637cbSDimitry Andric 101*700637cbSDimitry Andric void 102*700637cbSDimitry Andric applyMappingSrc(MachineInstr &MI, unsigned &OpIdx, 103*700637cbSDimitry Andric const SmallVectorImpl<RegBankLLTMappingApplyID> &MethodIDs, 104*700637cbSDimitry Andric SmallSet<Register, 4> &SgprWaterfallOperandRegs); 105*700637cbSDimitry Andric 106*700637cbSDimitry Andric void splitLoad(MachineInstr &MI, ArrayRef<LLT> LLTBreakdown, 107*700637cbSDimitry Andric LLT MergeTy = LLT()); 108*700637cbSDimitry Andric void widenLoad(MachineInstr &MI, LLT WideTy, LLT MergeTy = LLT()); 109*700637cbSDimitry Andric 110*700637cbSDimitry Andric void lower(MachineInstr &MI, const RegBankLLTMapping &Mapping, 111*700637cbSDimitry Andric SmallSet<Register, 4> &SgprWaterfallOperandRegs); 112*700637cbSDimitry Andric 113*700637cbSDimitry Andric void lowerVccExtToSel(MachineInstr &MI); 114*700637cbSDimitry Andric std::pair<Register, Register> unpackZExt(Register Reg); 115*700637cbSDimitry Andric std::pair<Register, Register> unpackSExt(Register Reg); 116*700637cbSDimitry Andric std::pair<Register, Register> unpackAExt(Register Reg); 117*700637cbSDimitry Andric void lowerUnpackBitShift(MachineInstr &MI); 118*700637cbSDimitry Andric void lowerV_BFE(MachineInstr &MI); 119*700637cbSDimitry Andric void lowerS_BFE(MachineInstr &MI); 120*700637cbSDimitry Andric void lowerSplitTo32(MachineInstr &MI); 121*700637cbSDimitry Andric void lowerSplitTo32Select(MachineInstr &MI); 122*700637cbSDimitry Andric void lowerSplitTo32SExtInReg(MachineInstr &MI); 123*700637cbSDimitry Andric }; 124*700637cbSDimitry Andric 125*700637cbSDimitry Andric } // end namespace AMDGPU 126*700637cbSDimitry Andric } // end namespace llvm 127*700637cbSDimitry Andric 128*700637cbSDimitry Andric #endif 129