1fee41517SMatt Arsenault //=== 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 14fee41517SMatt Arsenault #include "AMDGPUTargetMachine.h" 15fee41517SMatt Arsenault #include "AMDGPULegalizerInfo.h" 16fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/Combiner.h" 17fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 18fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 19fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 20fee41517SMatt Arsenault #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 21fee41517SMatt Arsenault #include "llvm/CodeGen/MachineDominators.h" 22fee41517SMatt Arsenault #include "llvm/CodeGen/MachineFunctionPass.h" 23fee41517SMatt Arsenault #include "llvm/CodeGen/TargetPassConfig.h" 24fee41517SMatt Arsenault #include "llvm/Support/Debug.h" 25fee41517SMatt Arsenault #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 26fee41517SMatt Arsenault 27fee41517SMatt Arsenault #define DEBUG_TYPE "amdgpu-postlegalizer-combiner" 28fee41517SMatt Arsenault 29fee41517SMatt Arsenault using namespace llvm; 30fee41517SMatt Arsenault using namespace MIPatternMatch; 31fee41517SMatt Arsenault 32fee41517SMatt Arsenault struct FMinFMaxLegacyInfo { 33fee41517SMatt Arsenault Register LHS; 34fee41517SMatt Arsenault Register RHS; 35fee41517SMatt Arsenault Register True; 36fee41517SMatt Arsenault Register False; 37fee41517SMatt Arsenault CmpInst::Predicate Pred; 38fee41517SMatt Arsenault }; 39fee41517SMatt Arsenault 40fee41517SMatt Arsenault // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize 41fee41517SMatt Arsenault static bool matchFMinFMaxLegacy(MachineInstr &MI, MachineRegisterInfo &MRI, 42fee41517SMatt Arsenault MachineFunction &MF, FMinFMaxLegacyInfo &Info) { 43fee41517SMatt Arsenault // FIXME: Combines should have subtarget predicates, and we shouldn't need 44fee41517SMatt Arsenault // this here. 45fee41517SMatt Arsenault if (!MF.getSubtarget<GCNSubtarget>().hasFminFmaxLegacy()) 46fee41517SMatt Arsenault return false; 47fee41517SMatt Arsenault 48fee41517SMatt Arsenault // FIXME: Type predicate on pattern 49fee41517SMatt Arsenault if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(32)) 50fee41517SMatt Arsenault return false; 51fee41517SMatt Arsenault 52fee41517SMatt Arsenault Register Cond = MI.getOperand(1).getReg(); 53fee41517SMatt Arsenault if (!MRI.hasOneNonDBGUse(Cond) || 54fee41517SMatt Arsenault !mi_match(Cond, MRI, 55fee41517SMatt Arsenault m_GFCmp(m_Pred(Info.Pred), m_Reg(Info.LHS), m_Reg(Info.RHS)))) 56fee41517SMatt Arsenault return false; 57fee41517SMatt Arsenault 58fee41517SMatt Arsenault Info.True = MI.getOperand(2).getReg(); 59fee41517SMatt Arsenault Info.False = MI.getOperand(3).getReg(); 60fee41517SMatt Arsenault 61fee41517SMatt Arsenault if (!(Info.LHS == Info.True && Info.RHS == Info.False) && 62fee41517SMatt Arsenault !(Info.LHS == Info.False && Info.RHS == Info.True)) 63fee41517SMatt Arsenault return false; 64fee41517SMatt Arsenault 65fee41517SMatt Arsenault switch (Info.Pred) { 66fee41517SMatt Arsenault case CmpInst::FCMP_FALSE: 67fee41517SMatt Arsenault case CmpInst::FCMP_OEQ: 68fee41517SMatt Arsenault case CmpInst::FCMP_ONE: 69fee41517SMatt Arsenault case CmpInst::FCMP_ORD: 70fee41517SMatt Arsenault case CmpInst::FCMP_UNO: 71fee41517SMatt Arsenault case CmpInst::FCMP_UEQ: 72fee41517SMatt Arsenault case CmpInst::FCMP_UNE: 73fee41517SMatt Arsenault case CmpInst::FCMP_TRUE: 74fee41517SMatt Arsenault return false; 75fee41517SMatt Arsenault default: 76fee41517SMatt Arsenault return true; 77fee41517SMatt Arsenault } 78fee41517SMatt Arsenault } 79fee41517SMatt Arsenault 80fee41517SMatt Arsenault static void applySelectFCmpToFMinToFMaxLegacy(MachineInstr &MI, 81fee41517SMatt Arsenault const FMinFMaxLegacyInfo &Info) { 82fee41517SMatt Arsenault 83fee41517SMatt Arsenault auto buildNewInst = [&MI](unsigned Opc, Register X, Register Y) { 84fee41517SMatt Arsenault MachineIRBuilder MIB(MI); 85fee41517SMatt Arsenault MIB.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags()); 86fee41517SMatt Arsenault }; 87fee41517SMatt Arsenault 88fee41517SMatt Arsenault switch (Info.Pred) { 89fee41517SMatt Arsenault case CmpInst::FCMP_ULT: 90fee41517SMatt Arsenault case CmpInst::FCMP_ULE: 91fee41517SMatt Arsenault if (Info.LHS == Info.True) 92fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 93fee41517SMatt Arsenault else 94fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 95fee41517SMatt Arsenault break; 96fee41517SMatt Arsenault case CmpInst::FCMP_OLE: 97fee41517SMatt Arsenault case CmpInst::FCMP_OLT: { 98fee41517SMatt Arsenault // We need to permute the operands to get the correct NaN behavior. The 99fee41517SMatt Arsenault // selected operand is the second one based on the failing compare with NaN, 100fee41517SMatt Arsenault // so permute it based on the compare type the hardware uses. 101fee41517SMatt Arsenault if (Info.LHS == Info.True) 102fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 103fee41517SMatt Arsenault else 104fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 105fee41517SMatt Arsenault break; 106fee41517SMatt Arsenault } 107fee41517SMatt Arsenault case CmpInst::FCMP_UGE: 108fee41517SMatt Arsenault case CmpInst::FCMP_UGT: { 109fee41517SMatt Arsenault if (Info.LHS == Info.True) 110fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 111fee41517SMatt Arsenault else 112fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 113fee41517SMatt Arsenault break; 114fee41517SMatt Arsenault } 115fee41517SMatt Arsenault case CmpInst::FCMP_OGT: 116fee41517SMatt Arsenault case CmpInst::FCMP_OGE: { 117fee41517SMatt Arsenault if (Info.LHS == Info.True) 118fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 119fee41517SMatt Arsenault else 120fee41517SMatt Arsenault buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 121fee41517SMatt Arsenault break; 122fee41517SMatt Arsenault } 123fee41517SMatt Arsenault default: 124fee41517SMatt Arsenault llvm_unreachable("predicate should not have matched"); 125fee41517SMatt Arsenault } 126fee41517SMatt Arsenault 127fee41517SMatt Arsenault MI.eraseFromParent(); 128fee41517SMatt Arsenault } 129fee41517SMatt Arsenault 130b27d255eSMatt Arsenault static bool matchUCharToFloat(MachineInstr &MI, MachineRegisterInfo &MRI, 131b27d255eSMatt Arsenault MachineFunction &MF, CombinerHelper &Helper) { 132b27d255eSMatt Arsenault Register DstReg = MI.getOperand(0).getReg(); 133b27d255eSMatt Arsenault 134b27d255eSMatt Arsenault // TODO: We could try to match extracting the higher bytes, which would be 135b27d255eSMatt Arsenault // easier if i8 vectors weren't promoted to i32 vectors, particularly after 136b27d255eSMatt Arsenault // types are legalized. v4i8 -> v4f32 is probably the only case to worry 137b27d255eSMatt Arsenault // about in practice. 138b27d255eSMatt Arsenault LLT Ty = MRI.getType(DstReg); 139b27d255eSMatt Arsenault if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) { 140db777eaeSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 141db777eaeSMatt Arsenault unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 142db777eaeSMatt Arsenault assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64); 143db777eaeSMatt Arsenault const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8); 144db777eaeSMatt Arsenault return Helper.getKnownBits()->maskedValueIsZero(SrcReg, Mask); 145b27d255eSMatt Arsenault } 146b27d255eSMatt Arsenault 147b27d255eSMatt Arsenault return false; 148b27d255eSMatt Arsenault } 149b27d255eSMatt Arsenault 150b27d255eSMatt Arsenault static void applyUCharToFloat(MachineInstr &MI) { 151b27d255eSMatt Arsenault MachineIRBuilder B(MI); 152b27d255eSMatt Arsenault 153b27d255eSMatt Arsenault const LLT S32 = LLT::scalar(32); 154b27d255eSMatt Arsenault 155b27d255eSMatt Arsenault Register DstReg = MI.getOperand(0).getReg(); 156db777eaeSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 157b27d255eSMatt Arsenault LLT Ty = B.getMRI()->getType(DstReg); 158db777eaeSMatt Arsenault LLT SrcTy = B.getMRI()->getType(SrcReg); 159db777eaeSMatt Arsenault if (SrcTy != S32) 160db777eaeSMatt Arsenault SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0); 161b27d255eSMatt Arsenault 162b27d255eSMatt Arsenault if (Ty == S32) { 163b27d255eSMatt Arsenault B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, 164db777eaeSMatt Arsenault {SrcReg}, MI.getFlags()); 165b27d255eSMatt Arsenault } else { 166b27d255eSMatt Arsenault auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, 167db777eaeSMatt Arsenault {SrcReg}, MI.getFlags()); 168b27d255eSMatt Arsenault B.buildFPTrunc(DstReg, Cvt0, MI.getFlags()); 169b27d255eSMatt Arsenault } 170b27d255eSMatt Arsenault 171b27d255eSMatt Arsenault MI.eraseFromParent(); 172b27d255eSMatt Arsenault } 173fee41517SMatt Arsenault 1740ba40d4cSMatt Arsenault // FIXME: Should be able to have 2 separate matchdatas rather than custom struct 1750ba40d4cSMatt Arsenault // boilerplate. 1760ba40d4cSMatt Arsenault struct CvtF32UByteMatchInfo { 1770ba40d4cSMatt Arsenault Register CvtVal; 1780ba40d4cSMatt Arsenault unsigned ShiftOffset; 1790ba40d4cSMatt Arsenault }; 1800ba40d4cSMatt Arsenault 1810ba40d4cSMatt Arsenault static bool matchCvtF32UByteN(MachineInstr &MI, MachineRegisterInfo &MRI, 1820ba40d4cSMatt Arsenault MachineFunction &MF, 1830ba40d4cSMatt Arsenault CvtF32UByteMatchInfo &MatchInfo) { 1840ba40d4cSMatt Arsenault Register SrcReg = MI.getOperand(1).getReg(); 1850ba40d4cSMatt Arsenault 1860ba40d4cSMatt Arsenault // Look through G_ZEXT. 1870ba40d4cSMatt Arsenault mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg))); 1880ba40d4cSMatt Arsenault 1890ba40d4cSMatt Arsenault Register Src0; 1900ba40d4cSMatt Arsenault int64_t ShiftAmt; 1910ba40d4cSMatt Arsenault bool IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt))); 1920ba40d4cSMatt Arsenault if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) { 1930ba40d4cSMatt Arsenault const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0; 1940ba40d4cSMatt Arsenault 1950ba40d4cSMatt Arsenault unsigned ShiftOffset = 8 * Offset; 1960ba40d4cSMatt Arsenault if (IsShr) 1970ba40d4cSMatt Arsenault ShiftOffset += ShiftAmt; 1980ba40d4cSMatt Arsenault else 1990ba40d4cSMatt Arsenault ShiftOffset -= ShiftAmt; 2000ba40d4cSMatt Arsenault 2010ba40d4cSMatt Arsenault MatchInfo.CvtVal = Src0; 2020ba40d4cSMatt Arsenault MatchInfo.ShiftOffset = ShiftOffset; 2030ba40d4cSMatt Arsenault return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0; 2040ba40d4cSMatt Arsenault } 2050ba40d4cSMatt Arsenault 2060ba40d4cSMatt Arsenault // TODO: Simplify demanded bits. 2070ba40d4cSMatt Arsenault return false; 2080ba40d4cSMatt Arsenault } 2090ba40d4cSMatt Arsenault 2100ba40d4cSMatt Arsenault static void applyCvtF32UByteN(MachineInstr &MI, 2110ba40d4cSMatt Arsenault const CvtF32UByteMatchInfo &MatchInfo) { 2120ba40d4cSMatt Arsenault MachineIRBuilder B(MI); 2130ba40d4cSMatt Arsenault unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8; 2140ba40d4cSMatt Arsenault 2150ba40d4cSMatt Arsenault const LLT S32 = LLT::scalar(32); 2160ba40d4cSMatt Arsenault Register CvtSrc = MatchInfo.CvtVal; 2170ba40d4cSMatt Arsenault LLT SrcTy = B.getMRI()->getType(MatchInfo.CvtVal); 2180ba40d4cSMatt Arsenault if (SrcTy != S32) { 2190ba40d4cSMatt Arsenault assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8); 2200ba40d4cSMatt Arsenault CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0); 2210ba40d4cSMatt Arsenault } 2220ba40d4cSMatt Arsenault 2230ba40d4cSMatt Arsenault assert(MI.getOpcode() != NewOpc); 2240ba40d4cSMatt Arsenault B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags()); 2250ba40d4cSMatt Arsenault MI.eraseFromParent(); 2260ba40d4cSMatt Arsenault } 2270ba40d4cSMatt Arsenault 228fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 229fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 230fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 231fee41517SMatt Arsenault 232fee41517SMatt Arsenault namespace { 233fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 234fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 235fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 236fee41517SMatt Arsenault 23716bcd545SMatt Arsenault class AMDGPUPostLegalizerCombinerInfo final : public CombinerInfo { 238fee41517SMatt Arsenault GISelKnownBits *KB; 239fee41517SMatt Arsenault MachineDominatorTree *MDT; 240fee41517SMatt Arsenault 241fee41517SMatt Arsenault public: 242e35ba099SDaniel Sanders AMDGPUGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; 243fee41517SMatt Arsenault 244fee41517SMatt Arsenault AMDGPUPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 245fee41517SMatt Arsenault const AMDGPULegalizerInfo *LI, 246fee41517SMatt Arsenault GISelKnownBits *KB, MachineDominatorTree *MDT) 247fee41517SMatt Arsenault : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 248fee41517SMatt Arsenault /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 249fee41517SMatt Arsenault KB(KB), MDT(MDT) { 250e35ba099SDaniel Sanders if (!GeneratedRuleCfg.parseCommandLineOption()) 251fee41517SMatt Arsenault report_fatal_error("Invalid rule identifier"); 252fee41517SMatt Arsenault } 253fee41517SMatt Arsenault 254d15723efSMatt Arsenault bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 255fee41517SMatt Arsenault MachineIRBuilder &B) const override; 256fee41517SMatt Arsenault }; 257fee41517SMatt Arsenault 258fee41517SMatt Arsenault bool AMDGPUPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 259fee41517SMatt Arsenault MachineInstr &MI, 260fee41517SMatt Arsenault MachineIRBuilder &B) const { 261*66ffa0e9SMatt Arsenault CombinerHelper Helper(Observer, B, KB, MDT, LInfo); 262e35ba099SDaniel Sanders AMDGPUGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg); 263fee41517SMatt Arsenault 264fee41517SMatt Arsenault if (Generated.tryCombineAll(Observer, MI, B, Helper)) 265fee41517SMatt Arsenault return true; 266fee41517SMatt Arsenault 267fee41517SMatt Arsenault switch (MI.getOpcode()) { 268fee41517SMatt Arsenault case TargetOpcode::G_SHL: 269fee41517SMatt Arsenault case TargetOpcode::G_LSHR: 270fee41517SMatt Arsenault case TargetOpcode::G_ASHR: 271fee41517SMatt Arsenault // On some subtargets, 64-bit shift is a quarter rate instruction. In the 272fee41517SMatt Arsenault // common case, splitting this into a move and a 32-bit shift is faster and 273fee41517SMatt Arsenault // the same code size. 274fee41517SMatt Arsenault return Helper.tryCombineShiftToUnmerge(MI, 32); 275fee41517SMatt Arsenault } 276fee41517SMatt Arsenault 277fee41517SMatt Arsenault return false; 278fee41517SMatt Arsenault } 279fee41517SMatt Arsenault 280fee41517SMatt Arsenault #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 281fee41517SMatt Arsenault #include "AMDGPUGenPostLegalizeGICombiner.inc" 282fee41517SMatt Arsenault #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 283fee41517SMatt Arsenault 284fee41517SMatt Arsenault // Pass boilerplate 285fee41517SMatt Arsenault // ================ 286fee41517SMatt Arsenault 287fee41517SMatt Arsenault class AMDGPUPostLegalizerCombiner : public MachineFunctionPass { 288fee41517SMatt Arsenault public: 289fee41517SMatt Arsenault static char ID; 290fee41517SMatt Arsenault 291fee41517SMatt Arsenault AMDGPUPostLegalizerCombiner(bool IsOptNone = false); 292fee41517SMatt Arsenault 293fee41517SMatt Arsenault StringRef getPassName() const override { 294fee41517SMatt Arsenault return "AMDGPUPostLegalizerCombiner"; 295fee41517SMatt Arsenault } 296fee41517SMatt Arsenault 297fee41517SMatt Arsenault bool runOnMachineFunction(MachineFunction &MF) override; 298fee41517SMatt Arsenault 299fee41517SMatt Arsenault void getAnalysisUsage(AnalysisUsage &AU) const override; 300fee41517SMatt Arsenault private: 301fee41517SMatt Arsenault bool IsOptNone; 302fee41517SMatt Arsenault }; 303fee41517SMatt Arsenault } // end anonymous namespace 304fee41517SMatt Arsenault 305fee41517SMatt Arsenault void AMDGPUPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 306fee41517SMatt Arsenault AU.addRequired<TargetPassConfig>(); 307fee41517SMatt Arsenault AU.setPreservesCFG(); 308fee41517SMatt Arsenault getSelectionDAGFallbackAnalysisUsage(AU); 309fee41517SMatt Arsenault AU.addRequired<GISelKnownBitsAnalysis>(); 310fee41517SMatt Arsenault AU.addPreserved<GISelKnownBitsAnalysis>(); 311fee41517SMatt Arsenault if (!IsOptNone) { 312fee41517SMatt Arsenault AU.addRequired<MachineDominatorTree>(); 313fee41517SMatt Arsenault AU.addPreserved<MachineDominatorTree>(); 314fee41517SMatt Arsenault } 315fee41517SMatt Arsenault MachineFunctionPass::getAnalysisUsage(AU); 316fee41517SMatt Arsenault } 317fee41517SMatt Arsenault 318fee41517SMatt Arsenault AMDGPUPostLegalizerCombiner::AMDGPUPostLegalizerCombiner(bool IsOptNone) 319fee41517SMatt Arsenault : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 320fee41517SMatt Arsenault initializeAMDGPUPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 321fee41517SMatt Arsenault } 322fee41517SMatt Arsenault 323fee41517SMatt Arsenault bool AMDGPUPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 324fee41517SMatt Arsenault if (MF.getProperties().hasProperty( 325fee41517SMatt Arsenault MachineFunctionProperties::Property::FailedISel)) 326fee41517SMatt Arsenault return false; 327fee41517SMatt Arsenault auto *TPC = &getAnalysis<TargetPassConfig>(); 328fee41517SMatt Arsenault const Function &F = MF.getFunction(); 329fee41517SMatt Arsenault bool EnableOpt = 330fee41517SMatt Arsenault MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 331fee41517SMatt Arsenault 332fee41517SMatt Arsenault const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 333fee41517SMatt Arsenault const AMDGPULegalizerInfo *LI 334fee41517SMatt Arsenault = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo()); 335fee41517SMatt Arsenault 336fee41517SMatt Arsenault GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 337fee41517SMatt Arsenault MachineDominatorTree *MDT = 338fee41517SMatt Arsenault IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 339fee41517SMatt Arsenault AMDGPUPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 340fee41517SMatt Arsenault F.hasMinSize(), LI, KB, MDT); 341fee41517SMatt Arsenault Combiner C(PCInfo, TPC); 342fee41517SMatt Arsenault return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 343fee41517SMatt Arsenault } 344fee41517SMatt Arsenault 345fee41517SMatt Arsenault char AMDGPUPostLegalizerCombiner::ID = 0; 346fee41517SMatt Arsenault INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 347fee41517SMatt Arsenault "Combine AMDGPU machine instrs after legalization", 348fee41517SMatt Arsenault false, false) 349fee41517SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 350fee41517SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 351fee41517SMatt Arsenault INITIALIZE_PASS_END(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 352fee41517SMatt Arsenault "Combine AMDGPU machine instrs after legalization", false, 353fee41517SMatt Arsenault false) 354fee41517SMatt Arsenault 355fee41517SMatt Arsenault namespace llvm { 356fee41517SMatt Arsenault FunctionPass *createAMDGPUPostLegalizeCombiner(bool IsOptNone) { 357fee41517SMatt Arsenault return new AMDGPUPostLegalizerCombiner(IsOptNone); 358fee41517SMatt Arsenault } 359fee41517SMatt Arsenault } // end namespace llvm 360