xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
15ffd83dbSDimitry Andric //=== lib/CodeGen/GlobalISel/AMDGPUPreLegalizerCombiner.cpp ---------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric //
95ffd83dbSDimitry Andric // This pass does combining of machine instructions at the generic MI level,
105ffd83dbSDimitry Andric // before the legalizer.
115ffd83dbSDimitry Andric //
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
14e8d8bef9SDimitry Andric #include "AMDGPU.h"
15349cc55cSDimitry Andric #include "AMDGPUCombinerHelper.h"
16fe6060f1SDimitry Andric #include "AMDGPULegalizerInfo.h"
17fe6060f1SDimitry Andric #include "GCNSubtarget.h"
18fe6060f1SDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
1981ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
205ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h"
215ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
225ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
23*06c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
24*06c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
255ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
265ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
275ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
285ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
29e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h"
305ffd83dbSDimitry Andric 
31*06c3fb27SDimitry Andric #define GET_GICOMBINER_DEPS
32*06c3fb27SDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
33*06c3fb27SDimitry Andric #undef GET_GICOMBINER_DEPS
34*06c3fb27SDimitry Andric 
355ffd83dbSDimitry Andric #define DEBUG_TYPE "amdgpu-prelegalizer-combiner"
365ffd83dbSDimitry Andric 
375ffd83dbSDimitry Andric using namespace llvm;
385ffd83dbSDimitry Andric using namespace MIPatternMatch;
39*06c3fb27SDimitry Andric namespace {
405ffd83dbSDimitry Andric 
41*06c3fb27SDimitry Andric #define GET_GICOMBINER_TYPES
42*06c3fb27SDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
43*06c3fb27SDimitry Andric #undef GET_GICOMBINER_TYPES
44*06c3fb27SDimitry Andric 
45*06c3fb27SDimitry Andric class AMDGPUPreLegalizerCombinerImpl : public GIMatchTableExecutor {
46fe6060f1SDimitry Andric protected:
47*06c3fb27SDimitry Andric   const AMDGPUPreLegalizerCombinerImplRuleConfig &RuleConfig;
48*06c3fb27SDimitry Andric   const GCNSubtarget &STI;
49*06c3fb27SDimitry Andric 
50*06c3fb27SDimitry Andric   GISelChangeObserver &Observer;
51fe6060f1SDimitry Andric   MachineIRBuilder &B;
52fe6060f1SDimitry Andric   MachineFunction &MF;
53fe6060f1SDimitry Andric   MachineRegisterInfo &MRI;
54349cc55cSDimitry Andric   AMDGPUCombinerHelper &Helper;
55fe6060f1SDimitry Andric 
56fe6060f1SDimitry Andric public:
57*06c3fb27SDimitry Andric   AMDGPUPreLegalizerCombinerImpl(
58*06c3fb27SDimitry Andric       const AMDGPUPreLegalizerCombinerImplRuleConfig &RuleConfig,
59*06c3fb27SDimitry Andric       const GCNSubtarget &STI, GISelChangeObserver &Observer,
60*06c3fb27SDimitry Andric       MachineIRBuilder &B, AMDGPUCombinerHelper &Helper);
61*06c3fb27SDimitry Andric 
62*06c3fb27SDimitry Andric   static const char *getName() { return "AMDGPUPreLegalizerCombinerImpl"; }
63*06c3fb27SDimitry Andric 
64*06c3fb27SDimitry Andric   bool tryCombineAll(MachineInstr &I) const;
65fe6060f1SDimitry Andric 
66fe6060f1SDimitry Andric   struct ClampI64ToI16MatchInfo {
67fe6060f1SDimitry Andric     int64_t Cmp1 = 0;
68fe6060f1SDimitry Andric     int64_t Cmp2 = 0;
69fe6060f1SDimitry Andric     Register Origin;
70fe6060f1SDimitry Andric   };
71fe6060f1SDimitry Andric 
72*06c3fb27SDimitry Andric   bool matchClampI64ToI16(MachineInstr &MI, const MachineRegisterInfo &MRI,
73*06c3fb27SDimitry Andric                           const MachineFunction &MF,
74*06c3fb27SDimitry Andric                           ClampI64ToI16MatchInfo &MatchInfo) const;
75fe6060f1SDimitry Andric 
76fe6060f1SDimitry Andric   void applyClampI64ToI16(MachineInstr &MI,
77*06c3fb27SDimitry Andric                           const ClampI64ToI16MatchInfo &MatchInfo) const;
78*06c3fb27SDimitry Andric 
79*06c3fb27SDimitry Andric private:
80*06c3fb27SDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS
81*06c3fb27SDimitry Andric #define AMDGPUSubtarget GCNSubtarget
82*06c3fb27SDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
83*06c3fb27SDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS
84*06c3fb27SDimitry Andric #undef AMDGPUSubtarget
85fe6060f1SDimitry Andric };
86fe6060f1SDimitry Andric 
87*06c3fb27SDimitry Andric #define GET_GICOMBINER_IMPL
88*06c3fb27SDimitry Andric #define AMDGPUSubtarget GCNSubtarget
89*06c3fb27SDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
90*06c3fb27SDimitry Andric #undef AMDGPUSubtarget
91*06c3fb27SDimitry Andric #undef GET_GICOMBINER_IMPL
92*06c3fb27SDimitry Andric 
93*06c3fb27SDimitry Andric AMDGPUPreLegalizerCombinerImpl::AMDGPUPreLegalizerCombinerImpl(
94*06c3fb27SDimitry Andric     const AMDGPUPreLegalizerCombinerImplRuleConfig &RuleConfig,
95*06c3fb27SDimitry Andric     const GCNSubtarget &STI, GISelChangeObserver &Observer, MachineIRBuilder &B,
96*06c3fb27SDimitry Andric     AMDGPUCombinerHelper &Helper)
97*06c3fb27SDimitry Andric     : RuleConfig(RuleConfig), STI(STI), Observer(Observer), B(B), MF(B.getMF()),
98*06c3fb27SDimitry Andric       MRI(*B.getMRI()), Helper(Helper),
99*06c3fb27SDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS
100*06c3fb27SDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
101*06c3fb27SDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS
102*06c3fb27SDimitry Andric {
103*06c3fb27SDimitry Andric }
104*06c3fb27SDimitry Andric 
105*06c3fb27SDimitry Andric bool AMDGPUPreLegalizerCombinerImpl::matchClampI64ToI16(
106*06c3fb27SDimitry Andric     MachineInstr &MI, const MachineRegisterInfo &MRI, const MachineFunction &MF,
107*06c3fb27SDimitry Andric     ClampI64ToI16MatchInfo &MatchInfo) const {
108fe6060f1SDimitry Andric   assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Invalid instruction!");
109fe6060f1SDimitry Andric 
110fe6060f1SDimitry Andric   // Try to find a pattern where an i64 value should get clamped to short.
111fe6060f1SDimitry Andric   const LLT SrcType = MRI.getType(MI.getOperand(1).getReg());
112fe6060f1SDimitry Andric   if (SrcType != LLT::scalar(64))
113fe6060f1SDimitry Andric     return false;
114fe6060f1SDimitry Andric 
115fe6060f1SDimitry Andric   const LLT DstType = MRI.getType(MI.getOperand(0).getReg());
116fe6060f1SDimitry Andric   if (DstType != LLT::scalar(16))
117fe6060f1SDimitry Andric     return false;
118fe6060f1SDimitry Andric 
119fe6060f1SDimitry Andric   Register Base;
120fe6060f1SDimitry Andric 
121fe6060f1SDimitry Andric   auto IsApplicableForCombine = [&MatchInfo]() -> bool {
122fe6060f1SDimitry Andric     const auto Cmp1 = MatchInfo.Cmp1;
123fe6060f1SDimitry Andric     const auto Cmp2 = MatchInfo.Cmp2;
124fe6060f1SDimitry Andric     const auto Diff = std::abs(Cmp2 - Cmp1);
125fe6060f1SDimitry Andric 
126fe6060f1SDimitry Andric     // If the difference between both comparison values is 0 or 1, there is no
127fe6060f1SDimitry Andric     // need to clamp.
128fe6060f1SDimitry Andric     if (Diff == 0 || Diff == 1)
129fe6060f1SDimitry Andric       return false;
130fe6060f1SDimitry Andric 
131fe6060f1SDimitry Andric     const int64_t Min = std::numeric_limits<int16_t>::min();
132fe6060f1SDimitry Andric     const int64_t Max = std::numeric_limits<int16_t>::max();
133fe6060f1SDimitry Andric 
134fe6060f1SDimitry Andric     // Check if the comparison values are between SHORT_MIN and SHORT_MAX.
135fe6060f1SDimitry Andric     return ((Cmp2 >= Cmp1 && Cmp1 >= Min && Cmp2 <= Max) ||
136fe6060f1SDimitry Andric             (Cmp1 >= Cmp2 && Cmp1 <= Max && Cmp2 >= Min));
137fe6060f1SDimitry Andric   };
138fe6060f1SDimitry Andric 
139fe6060f1SDimitry Andric   // Try to match a combination of min / max MIR opcodes.
140fe6060f1SDimitry Andric   if (mi_match(MI.getOperand(1).getReg(), MRI,
141fe6060f1SDimitry Andric                m_GSMin(m_Reg(Base), m_ICst(MatchInfo.Cmp1)))) {
142fe6060f1SDimitry Andric     if (mi_match(Base, MRI,
143fe6060f1SDimitry Andric                  m_GSMax(m_Reg(MatchInfo.Origin), m_ICst(MatchInfo.Cmp2)))) {
144fe6060f1SDimitry Andric       return IsApplicableForCombine();
145fe6060f1SDimitry Andric     }
146fe6060f1SDimitry Andric   }
147fe6060f1SDimitry Andric 
148fe6060f1SDimitry Andric   if (mi_match(MI.getOperand(1).getReg(), MRI,
149fe6060f1SDimitry Andric                m_GSMax(m_Reg(Base), m_ICst(MatchInfo.Cmp1)))) {
150fe6060f1SDimitry Andric     if (mi_match(Base, MRI,
151fe6060f1SDimitry Andric                  m_GSMin(m_Reg(MatchInfo.Origin), m_ICst(MatchInfo.Cmp2)))) {
152fe6060f1SDimitry Andric       return IsApplicableForCombine();
153fe6060f1SDimitry Andric     }
154fe6060f1SDimitry Andric   }
155fe6060f1SDimitry Andric 
156fe6060f1SDimitry Andric   return false;
157fe6060f1SDimitry Andric }
158fe6060f1SDimitry Andric 
159fe6060f1SDimitry Andric // We want to find a combination of instructions that
160fe6060f1SDimitry Andric // gets generated when an i64 gets clamped to i16.
161fe6060f1SDimitry Andric // The corresponding pattern is:
162fe6060f1SDimitry Andric // G_MAX / G_MAX for i16 <= G_TRUNC i64.
163fe6060f1SDimitry Andric // This can be efficiently written as following:
164fe6060f1SDimitry Andric // v_cvt_pk_i16_i32 v0, v0, v1
165fe6060f1SDimitry Andric // v_med3_i32 v0, Clamp_Min, v0, Clamp_Max
166*06c3fb27SDimitry Andric void AMDGPUPreLegalizerCombinerImpl::applyClampI64ToI16(
167*06c3fb27SDimitry Andric     MachineInstr &MI, const ClampI64ToI16MatchInfo &MatchInfo) const {
168fe6060f1SDimitry Andric 
169fe6060f1SDimitry Andric   Register Src = MatchInfo.Origin;
170fe6060f1SDimitry Andric   assert(MI.getParent()->getParent()->getRegInfo().getType(Src) ==
171fe6060f1SDimitry Andric          LLT::scalar(64));
172fe6060f1SDimitry Andric   const LLT S32 = LLT::scalar(32);
173fe6060f1SDimitry Andric 
174fe6060f1SDimitry Andric   B.setInstrAndDebugLoc(MI);
175fe6060f1SDimitry Andric 
176fe6060f1SDimitry Andric   auto Unmerge = B.buildUnmerge(S32, Src);
177fe6060f1SDimitry Andric 
178fe6060f1SDimitry Andric   assert(MI.getOpcode() != AMDGPU::G_AMDGPU_CVT_PK_I16_I32);
179fe6060f1SDimitry Andric 
180fe6060f1SDimitry Andric   const LLT V2S16 = LLT::fixed_vector(2, 16);
181fe6060f1SDimitry Andric   auto CvtPk =
182fe6060f1SDimitry Andric       B.buildInstr(AMDGPU::G_AMDGPU_CVT_PK_I16_I32, {V2S16},
183fe6060f1SDimitry Andric                    {Unmerge.getReg(0), Unmerge.getReg(1)}, MI.getFlags());
184fe6060f1SDimitry Andric 
185fe6060f1SDimitry Andric   auto MinBoundary = std::min(MatchInfo.Cmp1, MatchInfo.Cmp2);
186fe6060f1SDimitry Andric   auto MaxBoundary = std::max(MatchInfo.Cmp1, MatchInfo.Cmp2);
187fe6060f1SDimitry Andric   auto MinBoundaryDst = B.buildConstant(S32, MinBoundary);
188fe6060f1SDimitry Andric   auto MaxBoundaryDst = B.buildConstant(S32, MaxBoundary);
189fe6060f1SDimitry Andric 
190fe6060f1SDimitry Andric   auto Bitcast = B.buildBitcast({S32}, CvtPk);
191fe6060f1SDimitry Andric 
192fe6060f1SDimitry Andric   auto Med3 = B.buildInstr(
193fe6060f1SDimitry Andric       AMDGPU::G_AMDGPU_SMED3, {S32},
194fe6060f1SDimitry Andric       {MinBoundaryDst.getReg(0), Bitcast.getReg(0), MaxBoundaryDst.getReg(0)},
195fe6060f1SDimitry Andric       MI.getFlags());
196fe6060f1SDimitry Andric 
197fe6060f1SDimitry Andric   B.buildTrunc(MI.getOperand(0).getReg(), Med3);
198fe6060f1SDimitry Andric 
199fe6060f1SDimitry Andric   MI.eraseFromParent();
200fe6060f1SDimitry Andric }
201fe6060f1SDimitry Andric 
202e8d8bef9SDimitry Andric class AMDGPUPreLegalizerCombinerInfo final : public CombinerInfo {
2035ffd83dbSDimitry Andric   GISelKnownBits *KB;
2045ffd83dbSDimitry Andric   MachineDominatorTree *MDT;
205*06c3fb27SDimitry Andric   AMDGPUPreLegalizerCombinerImplRuleConfig RuleConfig;
2065ffd83dbSDimitry Andric 
2075ffd83dbSDimitry Andric public:
2085ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
2095ffd83dbSDimitry Andric                                  GISelKnownBits *KB, MachineDominatorTree *MDT)
2105ffd83dbSDimitry Andric       : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
2115ffd83dbSDimitry Andric                      /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize),
2125ffd83dbSDimitry Andric         KB(KB), MDT(MDT) {
213*06c3fb27SDimitry Andric     if (!RuleConfig.parseCommandLineOption())
2145ffd83dbSDimitry Andric       report_fatal_error("Invalid rule identifier");
2155ffd83dbSDimitry Andric   }
2165ffd83dbSDimitry Andric 
217972a253aSDimitry Andric   bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
2185ffd83dbSDimitry Andric                MachineIRBuilder &B) const override;
2195ffd83dbSDimitry Andric };
2205ffd83dbSDimitry Andric 
2215ffd83dbSDimitry Andric bool AMDGPUPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
2225ffd83dbSDimitry Andric                                              MachineInstr &MI,
2235ffd83dbSDimitry Andric                                              MachineIRBuilder &B) const {
224bdd1243dSDimitry Andric   const auto *LI = MI.getMF()->getSubtarget().getLegalizerInfo();
225bdd1243dSDimitry Andric   AMDGPUCombinerHelper Helper(Observer, B, /*IsPreLegalize*/ true, KB, MDT, LI);
2265ffd83dbSDimitry Andric 
227*06c3fb27SDimitry Andric   const GCNSubtarget &STI = MI.getMF()->getSubtarget<GCNSubtarget>();
228*06c3fb27SDimitry Andric   // TODO: Do not re-create the Impl on every inst, it should be per function.
229*06c3fb27SDimitry Andric   AMDGPUPreLegalizerCombinerImpl Impl(RuleConfig, STI, Observer, B, Helper);
230*06c3fb27SDimitry Andric   Impl.setupMF(*MI.getMF(), KB);
231*06c3fb27SDimitry Andric 
232*06c3fb27SDimitry Andric   if (Impl.tryCombineAll(MI))
2335ffd83dbSDimitry Andric     return true;
2345ffd83dbSDimitry Andric 
2355ffd83dbSDimitry Andric   switch (MI.getOpcode()) {
2365ffd83dbSDimitry Andric   case TargetOpcode::G_CONCAT_VECTORS:
2375ffd83dbSDimitry Andric     return Helper.tryCombineConcatVectors(MI);
2385ffd83dbSDimitry Andric   case TargetOpcode::G_SHUFFLE_VECTOR:
2395ffd83dbSDimitry Andric     return Helper.tryCombineShuffleVector(MI);
2405ffd83dbSDimitry Andric   }
2415ffd83dbSDimitry Andric 
2425ffd83dbSDimitry Andric   return false;
2435ffd83dbSDimitry Andric }
2445ffd83dbSDimitry Andric 
2455ffd83dbSDimitry Andric // Pass boilerplate
2465ffd83dbSDimitry Andric // ================
2475ffd83dbSDimitry Andric 
2485ffd83dbSDimitry Andric class AMDGPUPreLegalizerCombiner : public MachineFunctionPass {
2495ffd83dbSDimitry Andric public:
2505ffd83dbSDimitry Andric   static char ID;
2515ffd83dbSDimitry Andric 
2525ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombiner(bool IsOptNone = false);
2535ffd83dbSDimitry Andric 
2545ffd83dbSDimitry Andric   StringRef getPassName() const override {
2555ffd83dbSDimitry Andric     return "AMDGPUPreLegalizerCombiner";
2565ffd83dbSDimitry Andric   }
2575ffd83dbSDimitry Andric 
2585ffd83dbSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
2595ffd83dbSDimitry Andric 
2605ffd83dbSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
261*06c3fb27SDimitry Andric 
2625ffd83dbSDimitry Andric private:
2635ffd83dbSDimitry Andric   bool IsOptNone;
2645ffd83dbSDimitry Andric };
2655ffd83dbSDimitry Andric } // end anonymous namespace
2665ffd83dbSDimitry Andric 
2675ffd83dbSDimitry Andric void AMDGPUPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
2685ffd83dbSDimitry Andric   AU.addRequired<TargetPassConfig>();
2695ffd83dbSDimitry Andric   AU.setPreservesCFG();
2705ffd83dbSDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
2715ffd83dbSDimitry Andric   AU.addRequired<GISelKnownBitsAnalysis>();
2725ffd83dbSDimitry Andric   AU.addPreserved<GISelKnownBitsAnalysis>();
2735ffd83dbSDimitry Andric   if (!IsOptNone) {
2745ffd83dbSDimitry Andric     AU.addRequired<MachineDominatorTree>();
2755ffd83dbSDimitry Andric     AU.addPreserved<MachineDominatorTree>();
2765ffd83dbSDimitry Andric   }
277fe6060f1SDimitry Andric 
278fe6060f1SDimitry Andric   AU.addRequired<GISelCSEAnalysisWrapperPass>();
279fe6060f1SDimitry Andric   AU.addPreserved<GISelCSEAnalysisWrapperPass>();
2805ffd83dbSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
2815ffd83dbSDimitry Andric }
2825ffd83dbSDimitry Andric 
2835ffd83dbSDimitry Andric AMDGPUPreLegalizerCombiner::AMDGPUPreLegalizerCombiner(bool IsOptNone)
2845ffd83dbSDimitry Andric     : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
2855ffd83dbSDimitry Andric   initializeAMDGPUPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
2865ffd83dbSDimitry Andric }
2875ffd83dbSDimitry Andric 
2885ffd83dbSDimitry Andric bool AMDGPUPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
2895ffd83dbSDimitry Andric   if (MF.getProperties().hasProperty(
2905ffd83dbSDimitry Andric           MachineFunctionProperties::Property::FailedISel))
2915ffd83dbSDimitry Andric     return false;
2925ffd83dbSDimitry Andric   auto *TPC = &getAnalysis<TargetPassConfig>();
2935ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
2945ffd83dbSDimitry Andric   bool EnableOpt =
2955ffd83dbSDimitry Andric       MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
2965ffd83dbSDimitry Andric   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
2975ffd83dbSDimitry Andric   MachineDominatorTree *MDT =
2985ffd83dbSDimitry Andric       IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
2995ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
3005ffd83dbSDimitry Andric                                         F.hasMinSize(), KB, MDT);
301fe6060f1SDimitry Andric   // Enable CSE.
302fe6060f1SDimitry Andric   GISelCSEAnalysisWrapper &Wrapper =
303fe6060f1SDimitry Andric       getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
304fe6060f1SDimitry Andric   auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig());
305fe6060f1SDimitry Andric 
3065ffd83dbSDimitry Andric   Combiner C(PCInfo, TPC);
307fe6060f1SDimitry Andric   return C.combineMachineInstrs(MF, CSEInfo);
3085ffd83dbSDimitry Andric }
3095ffd83dbSDimitry Andric 
3105ffd83dbSDimitry Andric char AMDGPUPreLegalizerCombiner::ID = 0;
3115ffd83dbSDimitry Andric INITIALIZE_PASS_BEGIN(AMDGPUPreLegalizerCombiner, DEBUG_TYPE,
3125ffd83dbSDimitry Andric                       "Combine AMDGPU machine instrs before legalization",
3135ffd83dbSDimitry Andric                       false, false)
3145ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
3155ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
3165ffd83dbSDimitry Andric INITIALIZE_PASS_END(AMDGPUPreLegalizerCombiner, DEBUG_TYPE,
3175ffd83dbSDimitry Andric                     "Combine AMDGPU machine instrs before legalization", false,
3185ffd83dbSDimitry Andric                     false)
3195ffd83dbSDimitry Andric 
3205ffd83dbSDimitry Andric namespace llvm {
3215ffd83dbSDimitry Andric FunctionPass *createAMDGPUPreLegalizeCombiner(bool IsOptNone) {
3225ffd83dbSDimitry Andric   return new AMDGPUPreLegalizerCombiner(IsOptNone);
3235ffd83dbSDimitry Andric }
3245ffd83dbSDimitry Andric } // end namespace llvm
325