LLVM  14.0.0git
AMDGPURegBankCombiner.cpp
Go to the documentation of this file.
1 //=== lib/CodeGen/GlobalISel/AMDGPURegBankCombiner.cpp ---------------===//
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 // This pass does combining of machine instructions at the generic MI level,
10 // after register banks are known.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AMDGPU.h"
15 #include "AMDGPULegalizerInfo.h"
16 #include "AMDGPURegisterBankInfo.h"
17 #include "GCNSubtarget.h"
27 #define DEBUG_TYPE "amdgpu-regbank-combiner"
28 
29 using namespace llvm;
30 using namespace MIPatternMatch;
31 
33 protected:
40 
41 public:
43  : B(B), MF(B.getMF()), MRI(*B.getMRI()),
44  RBI(*MF.getSubtarget().getRegBankInfo()),
45  TRI(*MF.getSubtarget().getRegisterInfo()), Helper(Helper){};
46 
47  bool isVgprRegBank(Register Reg);
48 
49  struct MinMaxMedOpc {
50  unsigned Min, Max, Med;
51  };
52 
53  struct Med3MatchInfo {
54  unsigned Opc;
55  Register Val0, Val1, Val2;
56  };
57 
58  MinMaxMedOpc getMinMaxPair(unsigned Opc);
59 
60  template <class m_Cst>
61  bool matchMed(MachineInstr &MI, MachineRegisterInfo &MRI, MinMaxMedOpc MMMOpc,
62  Register &Val, Register &K0, Register &K1);
63 
64  bool matchIntMinMaxToMed3(MachineInstr &MI, Med3MatchInfo &MatchInfo);
65  void applyMed3(MachineInstr &MI, Med3MatchInfo &MatchInfo);
66 };
67 
69  return RBI.getRegBank(Reg, MRI, TRI)->getID() == AMDGPU::VGPRRegBankID;
70 }
71 
74  switch (Opc) {
75  default:
76  llvm_unreachable("Unsupported opcode");
77  case AMDGPU::G_SMAX:
78  case AMDGPU::G_SMIN:
79  return {AMDGPU::G_SMIN, AMDGPU::G_SMAX, AMDGPU::G_AMDGPU_SMED3};
80  case AMDGPU::G_UMAX:
81  case AMDGPU::G_UMIN:
82  return {AMDGPU::G_UMIN, AMDGPU::G_UMAX, AMDGPU::G_AMDGPU_UMED3};
83  }
84 }
85 
86 template <class m_Cst>
89  MinMaxMedOpc MMMOpc, Register &Val,
90  Register &K0, Register &K1) {
91  // 4 operand commutes of: min(max(Val, K0), K1).
92  // Find K1 from outer instr: min(max(...), K1) or min(K1, max(...)).
93  // Find K0 and Val from inner instr: max(K0, Val) or max(Val, K0).
94  // 4 operand commutes of: max(min(Val, K1), K0).
95  // Find K0 from outer instr: max(min(...), K0) or max(K0, min(...)).
96  // Find K1 and Val from inner instr: min(K1, Val) or min(Val, K1).
97  return mi_match(
98  MI, MRI,
99  m_any_of(
101  MMMOpc.Min, m_CommutativeBinOp(MMMOpc.Max, m_Reg(Val), m_Cst(K0)),
102  m_Cst(K1)),
104  MMMOpc.Max, m_CommutativeBinOp(MMMOpc.Min, m_Reg(Val), m_Cst(K1)),
105  m_Cst(K0))));
106 }
107 
109  MachineInstr &MI, Med3MatchInfo &MatchInfo) {
110  Register Dst = MI.getOperand(0).getReg();
111  if (!isVgprRegBank(Dst))
112  return false;
113 
114  if (MRI.getType(Dst).isVector())
115  return false;
116 
117  MinMaxMedOpc OpcodeTriple = getMinMaxPair(MI.getOpcode());
118  Register Val, K0, K1;
119  // Match min(max(Val, K0), K1) or max(min(Val, K1), K0). Then see if K0 <= K1.
120  if (!matchMed<ICstRegMatch>(MI, MRI, OpcodeTriple, Val, K0, K1))
121  return false;
122 
123  const APInt &K0_Imm = getConstantIntVRegVal(K0, MRI)->getValue();
124  const APInt &K1_Imm = getConstantIntVRegVal(K1, MRI)->getValue();
125  if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_SMED3 && K0_Imm.sgt(K1_Imm))
126  return false;
127  if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_UMED3 && K0_Imm.ugt(K1_Imm))
128  return false;
129 
130  MatchInfo = {OpcodeTriple.Med, Val, K0, K1};
131  return true;
132 }
133 
135  Med3MatchInfo &MatchInfo) {
136  B.setInstrAndDebugLoc(MI);
137  B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
138  {MatchInfo.Val0, MatchInfo.Val1, MatchInfo.Val2}, MI.getFlags());
139  MI.eraseFromParent();
140 }
141 
143 protected:
146 
147 public:
149  AMDGPURegBankCombinerHelper &RegBankHelper)
150  : Helper(Helper), RegBankHelper(RegBankHelper) {}
151 };
152 
153 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
154 #include "AMDGPUGenRegBankGICombiner.inc"
155 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
156 
157 namespace {
158 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
159 #include "AMDGPUGenRegBankGICombiner.inc"
160 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
161 
162 class AMDGPURegBankCombinerInfo final : public CombinerInfo {
163  GISelKnownBits *KB;
165 
166 public:
167  AMDGPUGenRegBankCombinerHelperRuleConfig GeneratedRuleCfg;
168 
169  AMDGPURegBankCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
170  const AMDGPULegalizerInfo *LI,
172  : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
173  /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize),
174  KB(KB), MDT(MDT) {
175  if (!GeneratedRuleCfg.parseCommandLineOption())
176  report_fatal_error("Invalid rule identifier");
177  }
178 
179  bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
180  MachineIRBuilder &B) const override;
181 };
182 
184  MachineInstr &MI,
185  MachineIRBuilder &B) const {
186  CombinerHelper Helper(Observer, B, KB, MDT);
187  AMDGPURegBankCombinerHelper RegBankHelper(B, Helper);
188  AMDGPUGenRegBankCombinerHelper Generated(GeneratedRuleCfg, Helper,
189  RegBankHelper);
190 
191  if (Generated.tryCombineAll(Observer, MI, B))
192  return true;
193 
194  return false;
195 }
196 
197 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
198 #include "AMDGPUGenRegBankGICombiner.inc"
199 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
200 
201 // Pass boilerplate
202 // ================
203 
204 class AMDGPURegBankCombiner : public MachineFunctionPass {
205 public:
206  static char ID;
207 
208  AMDGPURegBankCombiner(bool IsOptNone = false);
209 
210  StringRef getPassName() const override {
211  return "AMDGPURegBankCombiner";
212  }
213 
214  bool runOnMachineFunction(MachineFunction &MF) override;
215 
216  void getAnalysisUsage(AnalysisUsage &AU) const override;
217 private:
218  bool IsOptNone;
219 };
220 } // end anonymous namespace
221 
222 void AMDGPURegBankCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
224  AU.setPreservesCFG();
228  if (!IsOptNone) {
231  }
233 }
234 
235 AMDGPURegBankCombiner::AMDGPURegBankCombiner(bool IsOptNone)
236  : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
237  initializeAMDGPURegBankCombinerPass(*PassRegistry::getPassRegistry());
238 }
239 
240 bool AMDGPURegBankCombiner::runOnMachineFunction(MachineFunction &MF) {
241  if (MF.getProperties().hasProperty(
242  MachineFunctionProperties::Property::FailedISel))
243  return false;
244  auto *TPC = &getAnalysis<TargetPassConfig>();
245  const Function &F = MF.getFunction();
246  bool EnableOpt =
247  MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
248 
249  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
250  const AMDGPULegalizerInfo *LI
251  = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo());
252 
253  GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
254  MachineDominatorTree *MDT =
255  IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
256  AMDGPURegBankCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
257  F.hasMinSize(), LI, KB, MDT);
258  Combiner C(PCInfo, TPC);
259  return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
260 }
261 
263 INITIALIZE_PASS_BEGIN(AMDGPURegBankCombiner, DEBUG_TYPE,
264  "Combine AMDGPU machine instrs after regbankselect",
265  false, false)
268 INITIALIZE_PASS_END(AMDGPURegBankCombiner, DEBUG_TYPE,
269  "Combine AMDGPU machine instrs after regbankselect", false,
270  false)
271 
272 namespace llvm {
274  return new AMDGPURegBankCombiner(IsOptNone);
275 }
276 } // end namespace llvm
MIPatternMatch.h
llvm::TargetMachine::getOptLevel
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
Definition: TargetMachine.cpp:198
CombinerInfo.h
AMDGPURegBankCombinerHelper::MRI
MachineRegisterInfo & MRI
Definition: AMDGPURegBankCombiner.cpp:36
llvm::MachineFunctionProperties::hasProperty
bool hasProperty(Property P) const
Definition: MachineFunction.h:165
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
AMDGPURegBankCombinerHelper::Helper
CombinerHelper & Helper
Definition: AMDGPURegBankCombiner.cpp:39
llvm::MIPatternMatch::m_Reg
operand_type_match m_Reg()
Definition: MIPatternMatch.h:127
llvm::GISelKnownBits
Definition: GISelKnownBits.h:29
AMDGPURegBankCombinerHelper::getMinMaxPair
MinMaxMedOpc getMinMaxPair(unsigned Opc)
Definition: AMDGPURegBankCombiner.cpp:73
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::Function
Definition: Function.h:61
AMDGPURegBankCombinerHelper::MF
MachineFunction & MF
Definition: AMDGPURegBankCombiner.cpp:35
llvm::ConstantInt::getValue
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:133
AMDGPURegBankCombinerHelper::isVgprRegBank
bool isVgprRegBank(Register Reg)
Definition: AMDGPURegBankCombiner.cpp:68
GISelKnownBits.h
regbankselect
Combine AMDGPU machine instrs after regbankselect
Definition: AMDGPURegBankCombiner.cpp:269
AMDGPURegBankCombinerHelper::MinMaxMedOpc::Max
unsigned Max
Definition: AMDGPURegBankCombiner.cpp:50
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
AMDGPURegBankCombinerHelper::AMDGPURegBankCombinerHelper
AMDGPURegBankCombinerHelper(MachineIRBuilder &B, CombinerHelper &Helper)
Definition: AMDGPURegBankCombiner.cpp:42
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
llvm::APInt::ugt
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition: APInt.h:1275
llvm::getSelectionDAGFallbackAnalysisUsage
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:762
llvm::GCNSubtarget
Definition: GCNSubtarget.h:38
llvm::CombinerInfo
Definition: CombinerInfo.h:27
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
llvm::AMDGPULegalizerInfo
This class provides the information for the target register banks.
Definition: AMDGPULegalizerInfo.h:32
F
#define F(x, y, z)
Definition: MD5.cpp:56
AMDGPURegBankCombinerHelperState::RegBankHelper
AMDGPURegBankCombinerHelper & RegBankHelper
Definition: AMDGPURegBankCombiner.cpp:145
AMDGPURegBankCombinerHelper::matchMed
bool matchMed(MachineInstr &MI, MachineRegisterInfo &MRI, MinMaxMedOpc MMMOpc, Register &Val, Register &K0, Register &K1)
Definition: AMDGPURegBankCombiner.cpp:87
llvm::GISelKnownBitsAnalysis
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...
Definition: GISelKnownBits.h:113
TargetMachine.h
GCNSubtarget.h
AMDGPURegBankCombinerHelper::Med3MatchInfo
Definition: AMDGPURegBankCombiner.cpp:53
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition: MachineFunction.h:713
false
Definition: StackSlotColoring.cpp:142
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AMDGPURegBankCombinerHelper::MinMaxMedOpc::Min
unsigned Min
Definition: AMDGPURegBankCombiner.cpp:50
AMDGPURegBankCombinerHelperState::AMDGPURegBankCombinerHelperState
AMDGPURegBankCombinerHelperState(CombinerHelper &Helper, AMDGPURegBankCombinerHelper &RegBankHelper)
Definition: AMDGPURegBankCombiner.cpp:148
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::CombinerHelper
Definition: CombinerHelper.h:90
llvm::None
const NoneType None
Definition: None.h:23
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition: TargetPassConfig.h:84
AMDGPURegBankCombinerHelper
Definition: AMDGPURegBankCombiner.cpp:32
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:622
Combine
Hexagon Vector Combine
Definition: HexagonVectorCombine.cpp:1520
AMDGPURegBankCombinerHelper::Med3MatchInfo::Opc
unsigned Opc
Definition: AMDGPURegBankCombiner.cpp:54
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
AMDGPURegisterBankInfo.h
AMDGPUMCTargetDesc.h
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:212
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::Combiner
Definition: Combiner.h:27
DEBUG_TYPE
#define DEBUG_TYPE
Definition: AMDGPURegBankCombiner.cpp:27
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
AMDGPURegBankCombinerHelper::RBI
const RegisterBankInfo & RBI
Definition: AMDGPURegBankCombiner.cpp:37
llvm::MIPatternMatch::m_CommutativeBinOp
BinaryOpc_match< LHS, RHS, true > m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R)
Definition: MIPatternMatch.h:291
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:123
llvm::getConstantIntVRegVal
const ConstantInt * getConstantIntVRegVal(Register VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:368
TargetPassConfig.h
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:70
llvm::MachineFunction
Definition: MachineFunction.h:230
AMDGPURegBankCombinerHelper::applyMed3
void applyMed3(MachineInstr &MI, Med3MatchInfo &MatchInfo)
Definition: AMDGPURegBankCombiner.cpp:134
CombinerHelper.h
AMDGPURegBankCombinerHelper::Med3MatchInfo::Val2
Register Val2
Definition: AMDGPURegBankCombiner.cpp:55
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::createAMDGPURegBankCombiner
FunctionPass * createAMDGPURegBankCombiner(bool IsOptNone)
Definition: AMDGPURegBankCombiner.cpp:273
Combiner.h
llvm::MIPatternMatch::m_any_of
Or< Preds... > m_any_of(Preds &&... preds)
Definition: MIPatternMatch.h:171
AMDGPURegBankCombinerHelper::MinMaxMedOpc
Definition: AMDGPURegBankCombiner.cpp:49
llvm::GISelChangeObserver
Abstract class that contains various methods for clients to notify about changes.
Definition: GISelChangeObserver.h:29
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
AMDGPURegBankCombinerHelper::MinMaxMedOpc::Med
unsigned Med
Definition: AMDGPURegBankCombiner.cpp:50
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:588
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:618
AMDGPURegBankCombinerHelper::B
MachineIRBuilder & B
Definition: AMDGPURegBankCombiner.cpp:34
AMDGPULegalizerInfo.h
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
AMDGPURegBankCombinerHelperState
Definition: AMDGPURegBankCombiner.cpp:142
llvm::initializeAMDGPURegBankCombinerPass
void initializeAMDGPURegBankCombinerPass(PassRegistry &)
llvm::APInt::sgt
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition: APInt.h:1294
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::MIPatternMatch::mi_match
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
Definition: MIPatternMatch.h:24
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
AMDGPURegBankCombinerHelper::matchIntMinMaxToMed3
bool matchIntMinMaxToMed3(MachineInstr &MI, Med3MatchInfo &MatchInfo)
Definition: AMDGPURegBankCombiner.cpp:108
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
combine
vector combine
Definition: VectorCombine.cpp:1029
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(AMDGPURegBankCombiner, DEBUG_TYPE, "Combine AMDGPU machine instrs after regbankselect", false, false) INITIALIZE_PASS_END(AMDGPURegBankCombiner
AMDGPURegBankCombinerHelper::TRI
const TargetRegisterInfo & TRI
Definition: AMDGPURegBankCombiner.cpp:38
AMDGPURegBankCombinerHelperState::Helper
CombinerHelper & Helper
Definition: AMDGPURegBankCombiner.cpp:144
machine
coro Split coroutine into a set of functions driving its state machine
Definition: CoroSplit.cpp:2280
MachineDominators.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38