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, typename CstTy>
61  bool matchMed(MachineInstr &MI, MachineRegisterInfo &MRI, MinMaxMedOpc MMMOpc,
62  Register &Val, CstTy &K0, CstTy &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, typename CstTy>
89  MinMaxMedOpc MMMOpc, Register &Val,
90  CstTy &K0, CstTy &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;
119  Optional<ValueAndVReg> K0, K1;
120  // Match min(max(Val, K0), K1) or max(min(Val, K1), K0). Then see if K0 <= K1.
121  if (!matchMed<GCstAndRegMatch>(MI, MRI, OpcodeTriple, Val, K0, K1))
122  return false;
123 
124  if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_SMED3 && K0->Value.sgt(K1->Value))
125  return false;
126  if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_UMED3 && K0->Value.ugt(K1->Value))
127  return false;
128 
129  MatchInfo = {OpcodeTriple.Med, Val, K0->VReg, K1->VReg};
130  return true;
131 }
132 
134  Med3MatchInfo &MatchInfo) {
135  B.setInstrAndDebugLoc(MI);
136  B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
137  {MatchInfo.Val0, MatchInfo.Val1, MatchInfo.Val2}, MI.getFlags());
138  MI.eraseFromParent();
139 }
140 
142 protected:
145 
146 public:
148  AMDGPURegBankCombinerHelper &RegBankHelper)
149  : Helper(Helper), RegBankHelper(RegBankHelper) {}
150 };
151 
152 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
153 #include "AMDGPUGenRegBankGICombiner.inc"
154 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
155 
156 namespace {
157 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
158 #include "AMDGPUGenRegBankGICombiner.inc"
159 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
160 
161 class AMDGPURegBankCombinerInfo final : public CombinerInfo {
162  GISelKnownBits *KB;
164 
165 public:
166  AMDGPUGenRegBankCombinerHelperRuleConfig GeneratedRuleCfg;
167 
168  AMDGPURegBankCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
169  const AMDGPULegalizerInfo *LI,
171  : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
172  /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize),
173  KB(KB), MDT(MDT) {
174  if (!GeneratedRuleCfg.parseCommandLineOption())
175  report_fatal_error("Invalid rule identifier");
176  }
177 
178  bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
179  MachineIRBuilder &B) const override;
180 };
181 
183  MachineInstr &MI,
184  MachineIRBuilder &B) const {
185  CombinerHelper Helper(Observer, B, KB, MDT);
186  AMDGPURegBankCombinerHelper RegBankHelper(B, Helper);
187  AMDGPUGenRegBankCombinerHelper Generated(GeneratedRuleCfg, Helper,
188  RegBankHelper);
189 
190  if (Generated.tryCombineAll(Observer, MI, B))
191  return true;
192 
193  return false;
194 }
195 
196 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
197 #include "AMDGPUGenRegBankGICombiner.inc"
198 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
199 
200 // Pass boilerplate
201 // ================
202 
203 class AMDGPURegBankCombiner : public MachineFunctionPass {
204 public:
205  static char ID;
206 
207  AMDGPURegBankCombiner(bool IsOptNone = false);
208 
209  StringRef getPassName() const override {
210  return "AMDGPURegBankCombiner";
211  }
212 
213  bool runOnMachineFunction(MachineFunction &MF) override;
214 
215  void getAnalysisUsage(AnalysisUsage &AU) const override;
216 private:
217  bool IsOptNone;
218 };
219 } // end anonymous namespace
220 
221 void AMDGPURegBankCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
223  AU.setPreservesCFG();
227  if (!IsOptNone) {
230  }
232 }
233 
234 AMDGPURegBankCombiner::AMDGPURegBankCombiner(bool IsOptNone)
235  : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
236  initializeAMDGPURegBankCombinerPass(*PassRegistry::getPassRegistry());
237 }
238 
239 bool AMDGPURegBankCombiner::runOnMachineFunction(MachineFunction &MF) {
240  if (MF.getProperties().hasProperty(
241  MachineFunctionProperties::Property::FailedISel))
242  return false;
243  auto *TPC = &getAnalysis<TargetPassConfig>();
244  const Function &F = MF.getFunction();
245  bool EnableOpt =
246  MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
247 
248  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
249  const AMDGPULegalizerInfo *LI
250  = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo());
251 
252  GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
253  MachineDominatorTree *MDT =
254  IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
255  AMDGPURegBankCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
256  F.hasMinSize(), LI, KB, MDT);
257  Combiner C(PCInfo, TPC);
258  return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
259 }
260 
262 INITIALIZE_PASS_BEGIN(AMDGPURegBankCombiner, DEBUG_TYPE,
263  "Combine AMDGPU machine instrs after regbankselect",
264  false, false)
267 INITIALIZE_PASS_END(AMDGPURegBankCombiner, DEBUG_TYPE,
268  "Combine AMDGPU machine instrs after regbankselect", false,
269  false)
270 
271 namespace llvm {
273  return new AMDGPURegBankCombiner(IsOptNone);
274 }
275 } // end namespace llvm
MIPatternMatch.h
llvm::TargetMachine::getOptLevel
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
Definition: TargetMachine.cpp:188
CombinerInfo.h
AMDGPURegBankCombinerHelper::MRI
MachineRegisterInfo & MRI
Definition: AMDGPURegBankCombiner.cpp:36
llvm::MachineFunctionProperties::hasProperty
bool hasProperty(Property P) const
Definition: MachineFunction.h:169
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1558
AMDGPURegBankCombinerHelper::Helper
CombinerHelper & Helper
Definition: AMDGPURegBankCombiner.cpp:39
llvm::MIPatternMatch::m_Reg
operand_type_match m_Reg()
Definition: MIPatternMatch.h:152
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:62
AMDGPURegBankCombinerHelper::MF
MachineFunction & MF
Definition: AMDGPURegBankCombiner.cpp:35
AMDGPURegBankCombinerHelper::isVgprRegBank
bool isVgprRegBank(Register Reg)
Definition: AMDGPURegBankCombiner.cpp:68
GISelKnownBits.h
regbankselect
Combine AMDGPU machine instrs after regbankselect
Definition: AMDGPURegBankCombiner.cpp:268
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:233
AMDGPURegBankCombinerHelper::matchMed
bool matchMed(MachineInstr &MI, MachineRegisterInfo &MRI, MinMaxMedOpc MMMOpc, Register &Val, CstTy &K0, CstTy &K1)
Definition: AMDGPURegBankCombiner.cpp:87
llvm::APInt::ugt
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition: APInt.h:1114
llvm::Optional
Definition: APInt.h:33
llvm::getSelectionDAGFallbackAnalysisUsage
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:870
llvm::GCNSubtarget
Definition: GCNSubtarget.h:31
llvm::CombinerInfo
Definition: CombinerInfo.h:27
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
llvm::ValueAndVReg::Value
APInt Value
Definition: Utils.h:179
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
llvm::ValueAndVReg::VReg
Register VReg
Definition: Utils.h:180
AMDGPURegBankCombinerHelperState::RegBankHelper
AMDGPURegBankCombinerHelper & RegBankHelper
Definition: AMDGPURegBankCombiner.cpp:144
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:725
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:147
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:143
llvm::CombinerHelper
Definition: CombinerHelper.h:104
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:634
Combine
Hexagon Vector Combine
Definition: HexagonVectorCombine.cpp:1524
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:316
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:123
TargetPassConfig.h
llvm::MachineFunction
Definition: MachineFunction.h:234
AMDGPURegBankCombinerHelper::applyMed3
void applyMed3(MachineInstr &MI, Med3MatchInfo &MatchInfo)
Definition: AMDGPURegBankCombiner.cpp:133
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:57
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
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:272
Combiner.h
llvm::MIPatternMatch::m_any_of
Or< Preds... > m_any_of(Preds &&... preds)
Definition: MIPatternMatch.h:196
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:600
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:630
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:141
llvm::initializeAMDGPURegBankCombinerPass
void initializeAMDGPURegBankCombinerPass(PassRegistry &)
llvm::APInt::sgt
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition: APInt.h:1133
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:46
combine
vector combine
Definition: VectorCombine.cpp:1217
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:143
machine
coro Split coroutine into a set of functions driving its state machine
Definition: CoroSplit.cpp:2275
MachineDominators.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38