19a8da909SThomas Symalla //=== lib/CodeGen/GlobalISel/AMDGPUPostLegalizerCombiner.cpp ---------------===// 2fee41517SMatt Arsenault // 3fee41517SMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fee41517SMatt Arsenault // See https://llvm.org/LICENSE.txt for license information. 5fee41517SMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fee41517SMatt Arsenault // 7fee41517SMatt Arsenault //===----------------------------------------------------------------------===// 8fee41517SMatt Arsenault // 9fee41517SMatt Arsenault // This pass does combining of machine instructions at the generic MI level, 10fee41517SMatt Arsenault // after the legalizer. 11fee41517SMatt Arsenault // 12fee41517SMatt Arsenault //===----------------------------------------------------------------------===// 13fee41517SMatt Arsenault 14ec043967SThomas Symalla <<<<<<< HEAD 156a87e9b0Sdfukalov #include "AMDGPU.h" 16fee41517SMatt Arsenault #include "AMDGPULegalizerInfo.h" 17560d7e04Sdfukalov #include "GCNSubtarget.h" 18ec043967SThomas Symalla ======= 19ec043967SThomas Symalla #include "AMDGPULegalizerInfo.h" 20ec043967SThomas Symalla #include "AMDGPUTargetMachine.h" 21ec043967SThomas Symalla >>>>>>> clang-format 22560d7e04Sdfukalov #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 23fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/Combiner.h" 24fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 25fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 26fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 27fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 28fee41517SMatt Arsenault #include "llvm/CodeGen/MachineDominators.h" 29fee41517SMatt Arsenault #include "llvm/CodeGen/TargetPassConfig.h" 30ec043967SThomas Symalla <<<<<<< HEAD 316a87e9b0Sdfukalov #include "llvm/Target/TargetMachine.h" 32ec043967SThomas Symalla ======= 33ec043967SThomas Symalla #include "llvm/Support/Debug.h" 34ec043967SThomas Symalla >>>>>>> clang-format 35fee41517SMatt Arsenault 36fee41517SMatt Arsenault #define DEBUG_TYPE "amdgpu-postlegalizer-combiner" 37fee41517SMatt Arsenault 38fee41517SMatt Arsenault using namespace llvm; 39fee41517SMatt Arsenault using namespace MIPatternMatch; 40fee41517SMatt Arsenault 410031418dSPetar Avramovic class AMDGPUPostLegalizerCombinerHelper { 420031418dSPetar Avramovic protected: 430031418dSPetar Avramovic MachineIRBuilder &B; 440031418dSPetar Avramovic MachineFunction &MF; 450031418dSPetar Avramovic MachineRegisterInfo &MRI; 460031418dSPetar Avramovic CombinerHelper &Helper; 470031418dSPetar Avramovic 480031418dSPetar Avramovic public: 490031418dSPetar Avramovic AMDGPUPostLegalizerCombinerHelper(MachineIRBuilder &B, CombinerHelper &Helper) 500031418dSPetar Avramovic : B(B), MF(B.getMF()), MRI(*B.getMRI()), Helper(Helper){}; 510031418dSPetar Avramovic 52fee41517SMatt Arsenault struct FMinFMaxLegacyInfo { 53fee41517SMatt Arsenault Register LHS; 54fee41517SMatt Arsenault Register RHS; 55fee41517SMatt Arsenault Register True; 56fee41517SMatt Arsenault Register False; 57fee41517SMatt Arsenault CmpInst::Predicate Pred; 58fee41517SMatt Arsenault }; 59fee41517SMatt Arsenault 60fee41517SMatt Arsenault // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize 610031418dSPetar Avramovic bool matchFMinFMaxLegacy(MachineInstr &MI, FMinFMaxLegacyInfo &Info); 620031418dSPetar Avramovic void applySelectFCmpToFMinToFMaxLegacy(MachineInstr &MI, 630031418dSPetar Avramovic const FMinFMaxLegacyInfo &Info); 640031418dSPetar Avramovic 650031418dSPetar Avramovic bool matchUCharToFloat(MachineInstr &MI); 660031418dSPetar Avramovic void applyUCharToFloat(MachineInstr &MI); 670031418dSPetar Avramovic 680031418dSPetar Avramovic // FIXME: Should be able to have 2 separate matchdatas rather than custom 690031418dSPetar Avramovic // struct boilerplate. 700031418dSPetar Avramovic struct CvtF32UByteMatchInfo { 710031418dSPetar Avramovic Register CvtVal; 720031418dSPetar Avramovic unsigned ShiftOffset; 730031418dSPetar Avramovic }; 740031418dSPetar Avramovic 750031418dSPetar Avramovic bool matchCvtF32UByteN(MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo); 760031418dSPetar Avramovic void applyCvtF32UByteN(MachineInstr &MI, 770031418dSPetar Avramovic const CvtF32UByteMatchInfo &MatchInfo); 780031418dSPetar Avramovic }; 790031418dSPetar Avramovic 800031418dSPetar Avramovic bool AMDGPUPostLegalizerCombinerHelper::matchFMinFMaxLegacy( 810031418dSPetar Avramovic MachineInstr &MI, FMinFMaxLegacyInfo &Info) { 82fee41517SMatt Arsenault // FIXME: Combines should have subtarget predicates, and we shouldn't need 83fee41517SMatt Arsenault // this here. 84fee41517SMatt Arsenault if (!MF.getSubtarget<GCNSubtarget>().hasFminFmaxLegacy()) 85fee41517SMatt Arsenault return false; 86fee41517SMatt Arsenault 87fee41517SMatt Arsenault // FIXME: Type predicate on pattern 88fee41517SMatt Arsenault if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(32)) 89fee41517SMatt Arsenault return false; 90fee41517SMatt Arsenault 91fee41517SMatt Arsenault Register Cond = MI.getOperand(1).getReg(); 92fee41517SMatt Arsenault if (!MRI.hasOneNonDBGUse(Cond) || 93fee41517SMatt Arsenault !mi_match(Cond, MRI, 94fee41517SMatt Arsenault m_GFCmp(m_Pred(Info.Pred), m_Reg(Info.LHS), m_Reg(Info.RHS)))) 95fee41517SMatt Arsenault return false; 96fee41517SMatt Arsenault 97fee41517SMatt Arsenault Info.True = MI.getOperand(2).getReg(); 98fee41517SMatt Arsenault Info.False = MI.getOperand(3).getReg(); 99fee41517SMatt Arsenault 100fee41517SMatt Arsenault if (!(Info.LHS == Info.True && Info.RHS == Info.False) && 101fee41517SMatt Arsenault !(Info.LHS == Info.False && Info.RHS == Info.True)) 102fee41517SMatt Arsenault return false; 103fee41517SMatt Arsenault 104fee41517SMatt Arsenault switch (Info.Pred) { 105fee41517SMatt Arsenault case CmpInst::FCMP_FALSE: 106fee41517SMatt Arsenault case CmpInst::FCMP_OEQ: 107fee41517SMatt Arsenault case CmpInst::FCMP_ONE: 108fee41517SMatt Arsenault case CmpInst::FCMP_ORD: 109fee41517SMatt Arsenault case CmpInst::FCMP_UNO: 110fee41517SMatt Arsenault case CmpInst::FCMP_UEQ: 111fee41517SMatt Arsenault case CmpInst::FCMP_UNE: 112fee41517SMatt Arsenault case CmpInst::FCMP_TRUE: 113fee41517SMatt Arsenault return false; 114fee41517SMatt Arsenault default: 115fee41517SMatt Arsenault return true; 116fee41517SMatt Arsenault } 117fee41517SMatt Arsenault } 118fee41517SMatt Arsenault 1190031418dSPetar Avramovic void AMDGPUPostLegalizerCombinerHelper::applySelectFCmpToFMinToFMaxLegacy( 1200031418dSPetar Avramovic MachineInstr &MI, const FMinFMaxLegacyInfo &Info) { 1210031418dSPetar Avramovic B.setInstrAndDebugLoc(MI); 1220031418dSPetar Avramovic auto buildNewInst = [&MI, this](unsigned Opc, Register X, Register Y) { 1230031418dSPetar Avramovic B.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags()); 124fee41517SMatt Arsenault }; 125fee41517SMatt Arsenault 126fee41517SMatt Arsenault switch (Info.Pred) { 127fee41517SMatt Arsenault case CmpInst::FCMP_ULT: 128fee41517SMatt Arsenault case CmpInst::FCMP_ULE: 129fee41517SMatt Arsenault if (Info.LHS == Info.True) 130fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 131fee41517SMatt Arsenault else 132fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 133fee41517SMatt Arsenault break; 134fee41517SMatt Arsenault case CmpInst::FCMP_OLE: 135fee41517SMatt Arsenault case CmpInst::FCMP_OLT: { 136fee41517SMatt Arsenault // We need to permute the operands to get the correct NaN behavior. The 137fee41517SMatt Arsenault // selected operand is the second one based on the failing compare with NaN, 138fee41517SMatt Arsenault // so permute it based on the compare type the hardware uses. 139fee41517SMatt Arsenault if (Info.LHS == Info.True) 140fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 141fee41517SMatt Arsenault else 142fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 143fee41517SMatt Arsenault break; 144fee41517SMatt Arsenault } 145fee41517SMatt Arsenault case CmpInst::FCMP_UGE: 146fee41517SMatt Arsenault case CmpInst::FCMP_UGT: { 147fee41517SMatt Arsenault if (Info.LHS == Info.True) 148fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 149fee41517SMatt Arsenault else 150fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 151fee41517SMatt Arsenault break; 152fee41517SMatt Arsenault } 153fee41517SMatt Arsenault case CmpInst::FCMP_OGT: 154fee41517SMatt Arsenault case CmpInst::FCMP_OGE: { 155fee41517SMatt Arsenault if (Info.LHS == Info.True) 156fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 157fee41517SMatt Arsenault else 158fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 159fee41517SMatt Arsenault break; 160fee41517SMatt Arsenault } 161fee41517SMatt Arsenault default: 162fee41517SMatt Arsenault llvm_unreachable("predicate should not have matched"); 163fee41517SMatt Arsenault } 164fee41517SMatt Arsenault 165fee41517SMatt Arsenault MI.eraseFromParent(); 166fee41517SMatt Arsenault } 167fee41517SMatt Arsenault 1680031418dSPetar Avramovic bool AMDGPUPostLegalizerCombinerHelper::matchUCharToFloat(MachineInstr &MI) { 169b27d255eSMatt Arsenault Register DstReg = MI.getOperand(0).getReg(); 170b27d255eSMatt Arsenault 171b27d255eSMatt Arsenault // TODO: We could try to match extracting the higher bytes, which would be 172b27d255eSMatt Arsenault // easier if i8 vectors weren't promoted to i32 vectors, particularly after 173b27d255eSMatt Arsenault // types are legalized. v4i8 -> v4f32 is probably the only case to worry 174b27d255eSMatt Arsenault // about in practice. 175b27d255eSMatt Arsenault LLT Ty = MRI.getType(DstReg); 176b27d255eSMatt Arsenault if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) { 177db777eaeSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 178db777eaeSMatt Arsenault unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 179db777eaeSMatt Arsenault assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64); 180db777eaeSMatt Arsenault const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8); 181db777eaeSMatt Arsenault return Helper.getKnownBits()->maskedValueIsZero(SrcReg, Mask); 182b27d255eSMatt Arsenault } 183b27d255eSMatt Arsenault 184b27d255eSMatt Arsenault return false; 185b27d255eSMatt Arsenault } 186b27d255eSMatt Arsenault 1870031418dSPetar Avramovic void AMDGPUPostLegalizerCombinerHelper::applyUCharToFloat(MachineInstr &MI) { 1880031418dSPetar Avramovic B.setInstrAndDebugLoc(MI); 189b27d255eSMatt Arsenault 190b27d255eSMatt Arsenault const LLT S32 = LLT::scalar(32); 191b27d255eSMatt Arsenault 192b27d255eSMatt Arsenault Register DstReg = MI.getOperand(0).getReg(); 193db777eaeSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 1940031418dSPetar Avramovic LLT Ty = MRI.getType(DstReg); 1950031418dSPetar Avramovic LLT SrcTy = MRI.getType(SrcReg); 196db777eaeSMatt Arsenault if (SrcTy != S32) 197db777eaeSMatt Arsenault SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0); 198b27d255eSMatt Arsenault 199b27d255eSMatt Arsenault if (Ty == S32) { 200*ecbed4e0SThomas Symalla B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, 201*ecbed4e0SThomas Symalla {SrcReg}, MI.getFlags()); 202b27d255eSMatt Arsenault } else { 203*ecbed4e0SThomas Symalla auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, 204*ecbed4e0SThomas Symalla {SrcReg}, MI.getFlags()); 205b27d255eSMatt Arsenault B.buildFPTrunc(DstReg, Cvt0, MI.getFlags()); 206b27d255eSMatt Arsenault } 207b27d255eSMatt Arsenault 208b27d255eSMatt Arsenault MI.eraseFromParent(); 209b27d255eSMatt Arsenault } 210fee41517SMatt Arsenault 2110031418dSPetar Avramovic bool AMDGPUPostLegalizerCombinerHelper::matchCvtF32UByteN( 2120031418dSPetar Avramovic MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo) { 2130ba40d4cSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 2140ba40d4cSMatt Arsenault 2150ba40d4cSMatt Arsenault // Look through G_ZEXT. 2160ba40d4cSMatt Arsenault mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg))); 2170ba40d4cSMatt Arsenault 2180ba40d4cSMatt Arsenault Register Src0; 2190ba40d4cSMatt Arsenault int64_t ShiftAmt; 2200ba40d4cSMatt Arsenault bool IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt))); 2210ba40d4cSMatt Arsenault if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) { 2220ba40d4cSMatt Arsenault const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0; 2230ba40d4cSMatt Arsenault 2240ba40d4cSMatt Arsenault unsigned ShiftOffset = 8 * Offset; 2250ba40d4cSMatt Arsenault if (IsShr) 2260ba40d4cSMatt Arsenault ShiftOffset += ShiftAmt; 2270ba40d4cSMatt Arsenault else 2280ba40d4cSMatt Arsenault ShiftOffset -= ShiftAmt; 2290ba40d4cSMatt Arsenault 2300ba40d4cSMatt Arsenault MatchInfo.CvtVal = Src0; 2310ba40d4cSMatt Arsenault MatchInfo.ShiftOffset = ShiftOffset; 2320ba40d4cSMatt Arsenault return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0; 2330ba40d4cSMatt Arsenault } 2340ba40d4cSMatt Arsenault 2350ba40d4cSMatt Arsenault // TODO: Simplify demanded bits. 2360ba40d4cSMatt Arsenault return false; 2370ba40d4cSMatt Arsenault } 2380ba40d4cSMatt Arsenault 2390031418dSPetar Avramovic void AMDGPUPostLegalizerCombinerHelper::applyCvtF32UByteN( 2400031418dSPetar Avramovic MachineInstr &MI, const CvtF32UByteMatchInfo &MatchInfo) { 2410031418dSPetar Avramovic B.setInstrAndDebugLoc(MI); 2420ba40d4cSMatt Arsenault unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8; 2430ba40d4cSMatt Arsenault 2440ba40d4cSMatt Arsenault const LLT S32 = LLT::scalar(32); 2450ba40d4cSMatt Arsenault Register CvtSrc = MatchInfo.CvtVal; 2460031418dSPetar Avramovic LLT SrcTy = MRI.getType(MatchInfo.CvtVal); 2470ba40d4cSMatt Arsenault if (SrcTy != S32) { 2480ba40d4cSMatt Arsenault assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8); 2490ba40d4cSMatt Arsenault CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0); 2500ba40d4cSMatt Arsenault } 2510ba40d4cSMatt Arsenault 2520ba40d4cSMatt Arsenault assert(MI.getOpcode() != NewOpc); 2530ba40d4cSMatt Arsenault B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags()); 2540ba40d4cSMatt Arsenault MI.eraseFromParent(); 2550ba40d4cSMatt Arsenault } 2560ba40d4cSMatt Arsenault 2570031418dSPetar Avramovic class AMDGPUPostLegalizerCombinerHelperState { 2580031418dSPetar Avramovic protected: 2590031418dSPetar Avramovic CombinerHelper &Helper; 2600031418dSPetar Avramovic AMDGPUPostLegalizerCombinerHelper &PostLegalizerHelper; 2610031418dSPetar Avramovic 2620031418dSPetar Avramovic public: 2630031418dSPetar Avramovic AMDGPUPostLegalizerCombinerHelperState( 2640031418dSPetar Avramovic CombinerHelper &Helper, 2650031418dSPetar Avramovic AMDGPUPostLegalizerCombinerHelper &PostLegalizerHelper) 2660031418dSPetar Avramovic : Helper(Helper), PostLegalizerHelper(PostLegalizerHelper) {} 2670031418dSPetar Avramovic }; 2680031418dSPetar Avramovic 269fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 270fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 271fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 272fee41517SMatt Arsenault 273fee41517SMatt Arsenault namespace { 274fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 275fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 276fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 277fee41517SMatt Arsenault 27816bcd545SMatt Arsenault class AMDGPUPostLegalizerCombinerInfo final : public CombinerInfo { 279fee41517SMatt Arsenault GISelKnownBits *KB; 280fee41517SMatt Arsenault MachineDominatorTree *MDT; 281fee41517SMatt Arsenault 282fee41517SMatt Arsenault public: 283e35ba099SDaniel Sanders AMDGPUGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; 284fee41517SMatt Arsenault 285fee41517SMatt Arsenault AMDGPUPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 286fee41517SMatt Arsenault const AMDGPULegalizerInfo *LI, 287fee41517SMatt Arsenault GISelKnownBits *KB, MachineDominatorTree *MDT) 288fee41517SMatt Arsenault : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 289fee41517SMatt Arsenault /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 290fee41517SMatt Arsenault KB(KB), MDT(MDT) { 291e35ba099SDaniel Sanders if (!GeneratedRuleCfg.parseCommandLineOption()) 292fee41517SMatt Arsenault report_fatal_error("Invalid rule identifier"); 293fee41517SMatt Arsenault } 294fee41517SMatt Arsenault 295d15723efSMatt Arsenault bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 296fee41517SMatt Arsenault MachineIRBuilder &B) const override; 297fee41517SMatt Arsenault }; 298fee41517SMatt Arsenault 299fee41517SMatt Arsenault bool AMDGPUPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 300fee41517SMatt Arsenault MachineInstr &MI, 301fee41517SMatt Arsenault MachineIRBuilder &B) const { 30266ffa0e9SMatt Arsenault CombinerHelper Helper(Observer, B, KB, MDT, LInfo); 3030031418dSPetar Avramovic AMDGPUPostLegalizerCombinerHelper PostLegalizerHelper(B, Helper); 3040031418dSPetar Avramovic AMDGPUGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg, Helper, 3050031418dSPetar Avramovic PostLegalizerHelper); 306fee41517SMatt Arsenault 3070031418dSPetar Avramovic if (Generated.tryCombineAll(Observer, MI, B)) 308fee41517SMatt Arsenault return true; 309fee41517SMatt Arsenault 310fee41517SMatt Arsenault switch (MI.getOpcode()) { 311fee41517SMatt Arsenault case TargetOpcode::G_SHL: 312fee41517SMatt Arsenault case TargetOpcode::G_LSHR: 313fee41517SMatt Arsenault case TargetOpcode::G_ASHR: 314fee41517SMatt Arsenault // On some subtargets, 64-bit shift is a quarter rate instruction. In the 315fee41517SMatt Arsenault // common case, splitting this into a move and a 32-bit shift is faster and 316fee41517SMatt Arsenault // the same code size. 317fee41517SMatt Arsenault return Helper.tryCombineShiftToUnmerge(MI, 32); 318fee41517SMatt Arsenault } 319fee41517SMatt Arsenault 320fee41517SMatt Arsenault return false; 321fee41517SMatt Arsenault } 322fee41517SMatt Arsenault 323fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 324fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 325fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 326fee41517SMatt Arsenault 327fee41517SMatt Arsenault // Pass boilerplate 328fee41517SMatt Arsenault // ================ 329fee41517SMatt Arsenault 330fee41517SMatt Arsenault class AMDGPUPostLegalizerCombiner : public MachineFunctionPass { 331fee41517SMatt Arsenault public: 332fee41517SMatt Arsenault static char ID; 333fee41517SMatt Arsenault 334fee41517SMatt Arsenault AMDGPUPostLegalizerCombiner(bool IsOptNone = false); 335fee41517SMatt Arsenault 336fee41517SMatt Arsenault StringRef getPassName() const override { 337fee41517SMatt Arsenault return "AMDGPUPostLegalizerCombiner"; 338fee41517SMatt Arsenault } 339fee41517SMatt Arsenault 340fee41517SMatt Arsenault bool runOnMachineFunction(MachineFunction &MF) override; 341fee41517SMatt Arsenault 342fee41517SMatt Arsenault void getAnalysisUsage(AnalysisUsage &AU) const override; 343ec043967SThomas Symalla 344fee41517SMatt Arsenault private: 345fee41517SMatt Arsenault bool IsOptNone; 346fee41517SMatt Arsenault }; 347fee41517SMatt Arsenault } // end anonymous namespace 348fee41517SMatt Arsenault 349fee41517SMatt Arsenault void AMDGPUPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 350fee41517SMatt Arsenault AU.addRequired<TargetPassConfig>(); 351fee41517SMatt Arsenault AU.setPreservesCFG(); 352fee41517SMatt Arsenault getSelectionDAGFallbackAnalysisUsage(AU); 353fee41517SMatt Arsenault AU.addRequired<GISelKnownBitsAnalysis>(); 354fee41517SMatt Arsenault AU.addPreserved<GISelKnownBitsAnalysis>(); 355fee41517SMatt Arsenault if (!IsOptNone) { 356fee41517SMatt Arsenault AU.addRequired<MachineDominatorTree>(); 357fee41517SMatt Arsenault AU.addPreserved<MachineDominatorTree>(); 358fee41517SMatt Arsenault } 359fee41517SMatt Arsenault MachineFunctionPass::getAnalysisUsage(AU); 360fee41517SMatt Arsenault } 361fee41517SMatt Arsenault 362fee41517SMatt Arsenault AMDGPUPostLegalizerCombiner::AMDGPUPostLegalizerCombiner(bool IsOptNone) 363fee41517SMatt Arsenault : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 364fee41517SMatt Arsenault initializeAMDGPUPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 365fee41517SMatt Arsenault } 366fee41517SMatt Arsenault 367fee41517SMatt Arsenault bool AMDGPUPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 368fee41517SMatt Arsenault if (MF.getProperties().hasProperty( 369fee41517SMatt Arsenault MachineFunctionProperties::Property::FailedISel)) 370fee41517SMatt Arsenault return false; 371fee41517SMatt Arsenault auto *TPC = &getAnalysis<TargetPassConfig>(); 372fee41517SMatt Arsenault const Function &F = MF.getFunction(); 373fee41517SMatt Arsenault bool EnableOpt = 374fee41517SMatt Arsenault MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 375fee41517SMatt Arsenault 376fee41517SMatt Arsenault const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 377ec043967SThomas Symalla const AMDGPULegalizerInfo *LI = 378ec043967SThomas Symalla static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo()); 379fee41517SMatt Arsenault 380fee41517SMatt Arsenault GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 381fee41517SMatt Arsenault MachineDominatorTree *MDT = 382fee41517SMatt Arsenault IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 383fee41517SMatt Arsenault AMDGPUPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 384fee41517SMatt Arsenault F.hasMinSize(), LI, KB, MDT); 385fee41517SMatt Arsenault Combiner C(PCInfo, TPC); 386fee41517SMatt Arsenault return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 387fee41517SMatt Arsenault } 388fee41517SMatt Arsenault 389fee41517SMatt Arsenault char AMDGPUPostLegalizerCombiner::ID = 0; 390fee41517SMatt Arsenault INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 391ec043967SThomas Symalla "Combine AMDGPU machine instrs after legalization", false, 392ec043967SThomas Symalla false) 393fee41517SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 394fee41517SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 395fee41517SMatt Arsenault INITIALIZE_PASS_END(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 396fee41517SMatt Arsenault "Combine AMDGPU machine instrs after legalization", false, 397fee41517SMatt Arsenault false) 398fee41517SMatt Arsenault 399fee41517SMatt Arsenault namespace llvm { 400fee41517SMatt Arsenault FunctionPass *createAMDGPUPostLegalizeCombiner(bool IsOptNone) { 401fee41517SMatt Arsenault return new AMDGPUPostLegalizerCombiner(IsOptNone); 402fee41517SMatt Arsenault } 403fee41517SMatt Arsenault } // end namespace llvm 404