1//===- AMDGPURegBankLegalizeHelper ------------------------------*- 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
9#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZEHELPER_H
10#define LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZEHELPER_H
11
12#include "AMDGPURegBankLegalizeRules.h"
13#include "llvm/ADT/SmallSet.h"
14#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
15#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
16#include "llvm/CodeGen/MachineRegisterInfo.h"
17
18namespace llvm {
19
20class MachineIRBuilder;
21class SIInstrInfo;
22class SIMachineFunctionInfo;
23class GISelValueTracking;
24
25namespace AMDGPU {
26
27/// Holds waterfall loop information: the set of SGPR operand registers that
28/// need waterfalling, and an instruction range [Start, End) to wrap in the
29/// loop.
30struct WaterfallInfo {
31 SmallSet<Register, 4> SgprWaterfallOperandRegs;
32 MachineBasicBlock::iterator Start;
33 MachineBasicBlock::iterator End;
34};
35
36// Receives list of RegBankLLTMappingApplyID and applies register banks on all
37// operands. It is user's responsibility to provide RegBankLLTMappingApplyIDs
38// for all register operands, there is no need to specify NonReg for trailing
39// imm operands. This finishes selection of register banks if there is no need
40// to replace instruction. In other case InstApplyMethod will create new
41// instruction(s).
42class RegBankLegalizeHelper {
43 MachineFunction &MF;
44 const SIMachineFunctionInfo *MFI;
45 const GCNSubtarget &ST;
46 const SIInstrInfo &TII;
47 MachineIRBuilder &B;
48 MachineRegisterInfo &MRI;
49 const MachineUniformityInfo &MUI;
50 GISelValueTracking *VT;
51 const RegisterBankInfo &RBI;
52 MachineOptimizationRemarkEmitter MORE;
53 const RegBankLegalizeRules &RBLRules;
54 const bool IsWave32;
55 const RegisterBank *SgprRB;
56 const RegisterBank *VgprRB;
57 const RegisterBank *AgprRB;
58 const RegisterBank *VccRB;
59
60 static constexpr LLT S1 = LLT::scalar(SizeInBits: 1);
61 static constexpr LLT S16 = LLT::scalar(SizeInBits: 16);
62 static constexpr LLT S32 = LLT::scalar(SizeInBits: 32);
63 static constexpr LLT S64 = LLT::scalar(SizeInBits: 64);
64 static constexpr LLT S96 = LLT::scalar(SizeInBits: 96);
65 static constexpr LLT S128 = LLT::scalar(SizeInBits: 128);
66 static constexpr LLT S256 = LLT::scalar(SizeInBits: 256);
67
68 static constexpr LLT V2S16 = LLT::fixed_vector(NumElements: 2, ScalarSizeInBits: 16);
69 static constexpr LLT V4S16 = LLT::fixed_vector(NumElements: 4, ScalarSizeInBits: 16);
70 static constexpr LLT V6S16 = LLT::fixed_vector(NumElements: 6, ScalarSizeInBits: 16);
71 static constexpr LLT V8S16 = LLT::fixed_vector(NumElements: 8, ScalarSizeInBits: 16);
72 static constexpr LLT V16S16 = LLT::fixed_vector(NumElements: 16, ScalarSizeInBits: 16);
73 static constexpr LLT V32S16 = LLT::fixed_vector(NumElements: 32, ScalarSizeInBits: 16);
74
75 static constexpr LLT V2S32 = LLT::fixed_vector(NumElements: 2, ScalarSizeInBits: 32);
76 static constexpr LLT V3S32 = LLT::fixed_vector(NumElements: 3, ScalarSizeInBits: 32);
77 static constexpr LLT V4S32 = LLT::fixed_vector(NumElements: 4, ScalarSizeInBits: 32);
78 static constexpr LLT V6S32 = LLT::fixed_vector(NumElements: 6, ScalarSizeInBits: 32);
79 static constexpr LLT V7S32 = LLT::fixed_vector(NumElements: 7, ScalarSizeInBits: 32);
80 static constexpr LLT V8S32 = LLT::fixed_vector(NumElements: 8, ScalarSizeInBits: 32);
81 static constexpr LLT V16S32 = LLT::fixed_vector(NumElements: 16, ScalarSizeInBits: 32);
82
83 static constexpr LLT V2S64 = LLT::fixed_vector(NumElements: 2, ScalarSizeInBits: 64);
84 static constexpr LLT V3S64 = LLT::fixed_vector(NumElements: 3, ScalarSizeInBits: 64);
85 static constexpr LLT V4S64 = LLT::fixed_vector(NumElements: 4, ScalarSizeInBits: 64);
86 static constexpr LLT V8S64 = LLT::fixed_vector(NumElements: 8, ScalarSizeInBits: 64);
87 static constexpr LLT V16S64 = LLT::fixed_vector(NumElements: 16, ScalarSizeInBits: 64);
88
89 static constexpr LLT P1 = LLT::pointer(AddressSpace: 1, SizeInBits: 64);
90 static constexpr LLT P4 = LLT::pointer(AddressSpace: 4, SizeInBits: 64);
91 static constexpr LLT P6 = LLT::pointer(AddressSpace: 6, SizeInBits: 32);
92
93 const LLT I16 = LLT::integer(SizeInBits: 16);
94 const LLT I32 = LLT::integer(SizeInBits: 32);
95 const LLT I64 = LLT::integer(SizeInBits: 64);
96
97 MachineRegisterInfo::VRegAttrs SgprRB_I32 = {.RCOrRB: SgprRB, .Ty: I32};
98 MachineRegisterInfo::VRegAttrs SgprRB_I64 = {.RCOrRB: SgprRB, .Ty: I64};
99 MachineRegisterInfo::VRegAttrs VgprRB_I32 = {.RCOrRB: VgprRB, .Ty: I32};
100 MachineRegisterInfo::VRegAttrs VgprRB_I64 = {.RCOrRB: VgprRB, .Ty: I64};
101 MachineRegisterInfo::VRegAttrs VccRB_S1 = {.RCOrRB: VccRB, .Ty: S1};
102
103public:
104 RegBankLegalizeHelper(MachineIRBuilder &B, const MachineUniformityInfo &MUI,
105 GISelValueTracking *VT, const RegisterBankInfo &RBI,
106 const RegBankLegalizeRules &RBLRules);
107
108 bool findRuleAndApplyMapping(MachineInstr &MI);
109
110private:
111 bool executeInWaterfallLoop(MachineIRBuilder &B, const WaterfallInfo &WFI);
112
113 LLT getTyFromID(RegBankLLTMappingApplyID ID);
114 LLT getBTyFromID(RegBankLLTMappingApplyID ID, LLT Ty);
115
116 const RegisterBank *getRegBankFromID(RegBankLLTMappingApplyID ID);
117
118 bool
119 applyMappingDst(MachineInstr &MI, unsigned &OpIdx,
120 const SmallVectorImpl<RegBankLLTMappingApplyID> &MethodIDs);
121
122 bool
123 applyMappingSrc(MachineInstr &MI, unsigned &OpIdx,
124 const SmallVectorImpl<RegBankLLTMappingApplyID> &MethodIDs,
125 WaterfallInfo &WFI);
126
127 unsigned setBufferOffsets(MachineIRBuilder &B, Register CombinedOffset,
128 Register &VOffsetReg, Register &SOffsetReg,
129 int64_t &InstOffsetVal, Align Alignment);
130
131 bool splitLoad(MachineInstr &MI, ArrayRef<LLT> LLTBreakdown,
132 LLT MergeTy = LLT());
133 bool widenLoad(MachineInstr &MI, LLT WideTy, LLT MergeTy = LLT());
134 bool widenMMOToS32(GAnyLoad &MI) const;
135
136 bool lower(MachineInstr &MI, const RegBankLLTMapping &Mapping,
137 WaterfallInfo &WFI);
138
139 bool lowerVccExtToSel(MachineInstr &MI);
140 std::pair<Register, Register> unpackZExt(Register Reg);
141 std::pair<Register, Register> unpackSExt(Register Reg);
142 std::pair<Register, Register> unpackAExt(Register Reg);
143 std::pair<Register, Register> unpackAExtTruncS16(Register Reg);
144 bool lowerUnpackBitShift(MachineInstr &MI);
145 bool lowerV_BFE(MachineInstr &MI);
146 bool lowerS_BFE(MachineInstr &MI);
147 bool lowerUniMAD64(MachineInstr &MI);
148 bool lowerSplitTo32(MachineInstr &MI);
149 bool lowerSplitTo32Mul(MachineInstr &MI);
150 bool lowerSplitTo16(MachineInstr &MI);
151 bool lowerSplitTo32Select(MachineInstr &MI);
152 bool lowerSplitTo32SExtInReg(MachineInstr &MI);
153 bool lowerSplitBitCount64To32(MachineInstr &MI);
154 bool lowerUnpackMinMax(MachineInstr &MI);
155 bool lowerUnpackAExt(MachineInstr &MI);
156 bool lowerSBufToBuf(MachineInstr &MI, WaterfallInfo &WFI);
157 bool lowerExtrVecEltToSel(MachineInstr &MI);
158 bool lowerExtrVecEltTo32(MachineInstr &MI);
159 bool lowerInsVecEltToSel(MachineInstr &MI);
160 bool lowerInsVecEltTo32(MachineInstr &MI);
161 bool lowerAbsToNegMax(MachineInstr &MI);
162 bool lowerAbsToS32(MachineInstr &MI);
163 bool lowerSetRounding(MachineInstr &MI);
164 bool lowerGetRounding(MachineInstr &MI);
165 bool applyRegisterBanksVgprWithSgprRsrc(MachineInstr &MI, unsigned RsrcIdx);
166};
167
168} // end namespace AMDGPU
169} // end namespace llvm
170
171#endif
172