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