15ffd83dbSDimitry Andric //=== lib/CodeGen/GlobalISel/AMDGPUPostLegalizerCombiner.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 // after the legalizer. 115ffd83dbSDimitry Andric // 125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 135ffd83dbSDimitry Andric 145ffd83dbSDimitry Andric #include "AMDGPUTargetMachine.h" 155ffd83dbSDimitry Andric #include "AMDGPULegalizerInfo.h" 165ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h" 175ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 185ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 195ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 205ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 215ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 225ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 235ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 245ffd83dbSDimitry Andric #include "llvm/Support/Debug.h" 255ffd83dbSDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 265ffd83dbSDimitry Andric 275ffd83dbSDimitry Andric #define DEBUG_TYPE "amdgpu-postlegalizer-combiner" 285ffd83dbSDimitry Andric 295ffd83dbSDimitry Andric using namespace llvm; 305ffd83dbSDimitry Andric using namespace MIPatternMatch; 315ffd83dbSDimitry Andric 325ffd83dbSDimitry Andric struct FMinFMaxLegacyInfo { 335ffd83dbSDimitry Andric Register LHS; 345ffd83dbSDimitry Andric Register RHS; 355ffd83dbSDimitry Andric Register True; 365ffd83dbSDimitry Andric Register False; 375ffd83dbSDimitry Andric CmpInst::Predicate Pred; 385ffd83dbSDimitry Andric }; 395ffd83dbSDimitry Andric 405ffd83dbSDimitry Andric // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize 415ffd83dbSDimitry Andric static bool matchFMinFMaxLegacy(MachineInstr &MI, MachineRegisterInfo &MRI, 425ffd83dbSDimitry Andric MachineFunction &MF, FMinFMaxLegacyInfo &Info) { 435ffd83dbSDimitry Andric // FIXME: Combines should have subtarget predicates, and we shouldn't need 445ffd83dbSDimitry Andric // this here. 455ffd83dbSDimitry Andric if (!MF.getSubtarget<GCNSubtarget>().hasFminFmaxLegacy()) 465ffd83dbSDimitry Andric return false; 475ffd83dbSDimitry Andric 485ffd83dbSDimitry Andric // FIXME: Type predicate on pattern 495ffd83dbSDimitry Andric if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(32)) 505ffd83dbSDimitry Andric return false; 515ffd83dbSDimitry Andric 525ffd83dbSDimitry Andric Register Cond = MI.getOperand(1).getReg(); 535ffd83dbSDimitry Andric if (!MRI.hasOneNonDBGUse(Cond) || 545ffd83dbSDimitry Andric !mi_match(Cond, MRI, 555ffd83dbSDimitry Andric m_GFCmp(m_Pred(Info.Pred), m_Reg(Info.LHS), m_Reg(Info.RHS)))) 565ffd83dbSDimitry Andric return false; 575ffd83dbSDimitry Andric 585ffd83dbSDimitry Andric Info.True = MI.getOperand(2).getReg(); 595ffd83dbSDimitry Andric Info.False = MI.getOperand(3).getReg(); 605ffd83dbSDimitry Andric 615ffd83dbSDimitry Andric if (!(Info.LHS == Info.True && Info.RHS == Info.False) && 625ffd83dbSDimitry Andric !(Info.LHS == Info.False && Info.RHS == Info.True)) 635ffd83dbSDimitry Andric return false; 645ffd83dbSDimitry Andric 655ffd83dbSDimitry Andric switch (Info.Pred) { 665ffd83dbSDimitry Andric case CmpInst::FCMP_FALSE: 675ffd83dbSDimitry Andric case CmpInst::FCMP_OEQ: 685ffd83dbSDimitry Andric case CmpInst::FCMP_ONE: 695ffd83dbSDimitry Andric case CmpInst::FCMP_ORD: 705ffd83dbSDimitry Andric case CmpInst::FCMP_UNO: 715ffd83dbSDimitry Andric case CmpInst::FCMP_UEQ: 725ffd83dbSDimitry Andric case CmpInst::FCMP_UNE: 735ffd83dbSDimitry Andric case CmpInst::FCMP_TRUE: 745ffd83dbSDimitry Andric return false; 755ffd83dbSDimitry Andric default: 765ffd83dbSDimitry Andric return true; 775ffd83dbSDimitry Andric } 785ffd83dbSDimitry Andric } 795ffd83dbSDimitry Andric 805ffd83dbSDimitry Andric static void applySelectFCmpToFMinToFMaxLegacy(MachineInstr &MI, 815ffd83dbSDimitry Andric const FMinFMaxLegacyInfo &Info) { 825ffd83dbSDimitry Andric 835ffd83dbSDimitry Andric auto buildNewInst = [&MI](unsigned Opc, Register X, Register Y) { 845ffd83dbSDimitry Andric MachineIRBuilder MIB(MI); 855ffd83dbSDimitry Andric MIB.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags()); 865ffd83dbSDimitry Andric }; 875ffd83dbSDimitry Andric 885ffd83dbSDimitry Andric switch (Info.Pred) { 895ffd83dbSDimitry Andric case CmpInst::FCMP_ULT: 905ffd83dbSDimitry Andric case CmpInst::FCMP_ULE: 915ffd83dbSDimitry Andric if (Info.LHS == Info.True) 925ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 935ffd83dbSDimitry Andric else 945ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 955ffd83dbSDimitry Andric break; 965ffd83dbSDimitry Andric case CmpInst::FCMP_OLE: 975ffd83dbSDimitry Andric case CmpInst::FCMP_OLT: { 985ffd83dbSDimitry Andric // We need to permute the operands to get the correct NaN behavior. The 995ffd83dbSDimitry Andric // selected operand is the second one based on the failing compare with NaN, 1005ffd83dbSDimitry Andric // so permute it based on the compare type the hardware uses. 1015ffd83dbSDimitry Andric if (Info.LHS == Info.True) 1025ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 1035ffd83dbSDimitry Andric else 1045ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 1055ffd83dbSDimitry Andric break; 1065ffd83dbSDimitry Andric } 1075ffd83dbSDimitry Andric case CmpInst::FCMP_UGE: 1085ffd83dbSDimitry Andric case CmpInst::FCMP_UGT: { 1095ffd83dbSDimitry Andric if (Info.LHS == Info.True) 1105ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.RHS, Info.LHS); 1115ffd83dbSDimitry Andric else 1125ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.LHS, Info.RHS); 1135ffd83dbSDimitry Andric break; 1145ffd83dbSDimitry Andric } 1155ffd83dbSDimitry Andric case CmpInst::FCMP_OGT: 1165ffd83dbSDimitry Andric case CmpInst::FCMP_OGE: { 1175ffd83dbSDimitry Andric if (Info.LHS == Info.True) 1185ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMAX_LEGACY, Info.LHS, Info.RHS); 1195ffd83dbSDimitry Andric else 1205ffd83dbSDimitry Andric buildNewInst(AMDGPU::G_AMDGPU_FMIN_LEGACY, Info.RHS, Info.LHS); 1215ffd83dbSDimitry Andric break; 1225ffd83dbSDimitry Andric } 1235ffd83dbSDimitry Andric default: 1245ffd83dbSDimitry Andric llvm_unreachable("predicate should not have matched"); 1255ffd83dbSDimitry Andric } 1265ffd83dbSDimitry Andric 1275ffd83dbSDimitry Andric MI.eraseFromParent(); 1285ffd83dbSDimitry Andric } 1295ffd83dbSDimitry Andric 1305ffd83dbSDimitry Andric static bool matchUCharToFloat(MachineInstr &MI, MachineRegisterInfo &MRI, 1315ffd83dbSDimitry Andric MachineFunction &MF, CombinerHelper &Helper) { 1325ffd83dbSDimitry Andric Register DstReg = MI.getOperand(0).getReg(); 1335ffd83dbSDimitry Andric 1345ffd83dbSDimitry Andric // TODO: We could try to match extracting the higher bytes, which would be 1355ffd83dbSDimitry Andric // easier if i8 vectors weren't promoted to i32 vectors, particularly after 1365ffd83dbSDimitry Andric // types are legalized. v4i8 -> v4f32 is probably the only case to worry 1375ffd83dbSDimitry Andric // about in practice. 1385ffd83dbSDimitry Andric LLT Ty = MRI.getType(DstReg); 1395ffd83dbSDimitry Andric if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) { 1405ffd83dbSDimitry Andric Register SrcReg = MI.getOperand(1).getReg(); 1415ffd83dbSDimitry Andric unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 1425ffd83dbSDimitry Andric assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64); 1435ffd83dbSDimitry Andric const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8); 1445ffd83dbSDimitry Andric return Helper.getKnownBits()->maskedValueIsZero(SrcReg, Mask); 1455ffd83dbSDimitry Andric } 1465ffd83dbSDimitry Andric 1475ffd83dbSDimitry Andric return false; 1485ffd83dbSDimitry Andric } 1495ffd83dbSDimitry Andric 1505ffd83dbSDimitry Andric static void applyUCharToFloat(MachineInstr &MI) { 1515ffd83dbSDimitry Andric MachineIRBuilder B(MI); 1525ffd83dbSDimitry Andric 1535ffd83dbSDimitry Andric const LLT S32 = LLT::scalar(32); 1545ffd83dbSDimitry Andric 1555ffd83dbSDimitry Andric Register DstReg = MI.getOperand(0).getReg(); 1565ffd83dbSDimitry Andric Register SrcReg = MI.getOperand(1).getReg(); 1575ffd83dbSDimitry Andric LLT Ty = B.getMRI()->getType(DstReg); 1585ffd83dbSDimitry Andric LLT SrcTy = B.getMRI()->getType(SrcReg); 1595ffd83dbSDimitry Andric if (SrcTy != S32) 1605ffd83dbSDimitry Andric SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0); 1615ffd83dbSDimitry Andric 1625ffd83dbSDimitry Andric if (Ty == S32) { 1635ffd83dbSDimitry Andric B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, 1645ffd83dbSDimitry Andric {SrcReg}, MI.getFlags()); 1655ffd83dbSDimitry Andric } else { 1665ffd83dbSDimitry Andric auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, 1675ffd83dbSDimitry Andric {SrcReg}, MI.getFlags()); 1685ffd83dbSDimitry Andric B.buildFPTrunc(DstReg, Cvt0, MI.getFlags()); 1695ffd83dbSDimitry Andric } 1705ffd83dbSDimitry Andric 1715ffd83dbSDimitry Andric MI.eraseFromParent(); 1725ffd83dbSDimitry Andric } 1735ffd83dbSDimitry Andric 1745ffd83dbSDimitry Andric // FIXME: Should be able to have 2 separate matchdatas rather than custom struct 1755ffd83dbSDimitry Andric // boilerplate. 1765ffd83dbSDimitry Andric struct CvtF32UByteMatchInfo { 1775ffd83dbSDimitry Andric Register CvtVal; 1785ffd83dbSDimitry Andric unsigned ShiftOffset; 1795ffd83dbSDimitry Andric }; 1805ffd83dbSDimitry Andric 1815ffd83dbSDimitry Andric static bool matchCvtF32UByteN(MachineInstr &MI, MachineRegisterInfo &MRI, 1825ffd83dbSDimitry Andric MachineFunction &MF, 1835ffd83dbSDimitry Andric CvtF32UByteMatchInfo &MatchInfo) { 1845ffd83dbSDimitry Andric Register SrcReg = MI.getOperand(1).getReg(); 1855ffd83dbSDimitry Andric 1865ffd83dbSDimitry Andric // Look through G_ZEXT. 1875ffd83dbSDimitry Andric mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg))); 1885ffd83dbSDimitry Andric 1895ffd83dbSDimitry Andric Register Src0; 1905ffd83dbSDimitry Andric int64_t ShiftAmt; 1915ffd83dbSDimitry Andric bool IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt))); 1925ffd83dbSDimitry Andric if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) { 1935ffd83dbSDimitry Andric const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0; 1945ffd83dbSDimitry Andric 1955ffd83dbSDimitry Andric unsigned ShiftOffset = 8 * Offset; 1965ffd83dbSDimitry Andric if (IsShr) 1975ffd83dbSDimitry Andric ShiftOffset += ShiftAmt; 1985ffd83dbSDimitry Andric else 1995ffd83dbSDimitry Andric ShiftOffset -= ShiftAmt; 2005ffd83dbSDimitry Andric 2015ffd83dbSDimitry Andric MatchInfo.CvtVal = Src0; 2025ffd83dbSDimitry Andric MatchInfo.ShiftOffset = ShiftOffset; 2035ffd83dbSDimitry Andric return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0; 2045ffd83dbSDimitry Andric } 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric // TODO: Simplify demanded bits. 2075ffd83dbSDimitry Andric return false; 2085ffd83dbSDimitry Andric } 2095ffd83dbSDimitry Andric 2105ffd83dbSDimitry Andric static void applyCvtF32UByteN(MachineInstr &MI, 2115ffd83dbSDimitry Andric const CvtF32UByteMatchInfo &MatchInfo) { 2125ffd83dbSDimitry Andric MachineIRBuilder B(MI); 2135ffd83dbSDimitry Andric unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8; 2145ffd83dbSDimitry Andric 2155ffd83dbSDimitry Andric const LLT S32 = LLT::scalar(32); 2165ffd83dbSDimitry Andric Register CvtSrc = MatchInfo.CvtVal; 2175ffd83dbSDimitry Andric LLT SrcTy = B.getMRI()->getType(MatchInfo.CvtVal); 2185ffd83dbSDimitry Andric if (SrcTy != S32) { 2195ffd83dbSDimitry Andric assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8); 2205ffd83dbSDimitry Andric CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0); 2215ffd83dbSDimitry Andric } 2225ffd83dbSDimitry Andric 2235ffd83dbSDimitry Andric assert(MI.getOpcode() != NewOpc); 2245ffd83dbSDimitry Andric B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags()); 2255ffd83dbSDimitry Andric MI.eraseFromParent(); 2265ffd83dbSDimitry Andric } 2275ffd83dbSDimitry Andric 2285ffd83dbSDimitry Andric #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 2295ffd83dbSDimitry Andric #include "AMDGPUGenPostLegalizeGICombiner.inc" 2305ffd83dbSDimitry Andric #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 2315ffd83dbSDimitry Andric 2325ffd83dbSDimitry Andric namespace { 2335ffd83dbSDimitry Andric #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 2345ffd83dbSDimitry Andric #include "AMDGPUGenPostLegalizeGICombiner.inc" 2355ffd83dbSDimitry Andric #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 2365ffd83dbSDimitry Andric 2375ffd83dbSDimitry Andric class AMDGPUPostLegalizerCombinerInfo : public CombinerInfo { 2385ffd83dbSDimitry Andric GISelKnownBits *KB; 2395ffd83dbSDimitry Andric MachineDominatorTree *MDT; 2405ffd83dbSDimitry Andric 2415ffd83dbSDimitry Andric public: 2425ffd83dbSDimitry Andric AMDGPUGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; 2435ffd83dbSDimitry Andric 2445ffd83dbSDimitry Andric AMDGPUPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 2455ffd83dbSDimitry Andric const AMDGPULegalizerInfo *LI, 2465ffd83dbSDimitry Andric GISelKnownBits *KB, MachineDominatorTree *MDT) 2475ffd83dbSDimitry Andric : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 2485ffd83dbSDimitry Andric /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 2495ffd83dbSDimitry Andric KB(KB), MDT(MDT) { 2505ffd83dbSDimitry Andric if (!GeneratedRuleCfg.parseCommandLineOption()) 2515ffd83dbSDimitry Andric report_fatal_error("Invalid rule identifier"); 2525ffd83dbSDimitry Andric } 2535ffd83dbSDimitry Andric 2545ffd83dbSDimitry Andric bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 2555ffd83dbSDimitry Andric MachineIRBuilder &B) const override; 2565ffd83dbSDimitry Andric }; 2575ffd83dbSDimitry Andric 2585ffd83dbSDimitry Andric bool AMDGPUPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 2595ffd83dbSDimitry Andric MachineInstr &MI, 2605ffd83dbSDimitry Andric MachineIRBuilder &B) const { 2615ffd83dbSDimitry Andric CombinerHelper Helper(Observer, B, KB, MDT); 2625ffd83dbSDimitry Andric AMDGPUGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg); 2635ffd83dbSDimitry Andric 2645ffd83dbSDimitry Andric if (Generated.tryCombineAll(Observer, MI, B, Helper)) 2655ffd83dbSDimitry Andric return true; 2665ffd83dbSDimitry Andric 2675ffd83dbSDimitry Andric switch (MI.getOpcode()) { 2685ffd83dbSDimitry Andric case TargetOpcode::G_SHL: 2695ffd83dbSDimitry Andric case TargetOpcode::G_LSHR: 2705ffd83dbSDimitry Andric case TargetOpcode::G_ASHR: 2715ffd83dbSDimitry Andric // On some subtargets, 64-bit shift is a quarter rate instruction. In the 2725ffd83dbSDimitry Andric // common case, splitting this into a move and a 32-bit shift is faster and 2735ffd83dbSDimitry Andric // the same code size. 2745ffd83dbSDimitry Andric return Helper.tryCombineShiftToUnmerge(MI, 32); 2755ffd83dbSDimitry Andric } 2765ffd83dbSDimitry Andric 2775ffd83dbSDimitry Andric return false; 2785ffd83dbSDimitry Andric } 2795ffd83dbSDimitry Andric 2805ffd83dbSDimitry Andric #define AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 2815ffd83dbSDimitry Andric #include "AMDGPUGenPostLegalizeGICombiner.inc" 2825ffd83dbSDimitry Andric #undef AMDGPUPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 2835ffd83dbSDimitry Andric 2845ffd83dbSDimitry Andric // Pass boilerplate 2855ffd83dbSDimitry Andric // ================ 2865ffd83dbSDimitry Andric 2875ffd83dbSDimitry Andric class AMDGPUPostLegalizerCombiner : public MachineFunctionPass { 2885ffd83dbSDimitry Andric public: 2895ffd83dbSDimitry Andric static char ID; 2905ffd83dbSDimitry Andric 2915ffd83dbSDimitry Andric AMDGPUPostLegalizerCombiner(bool IsOptNone = false); 2925ffd83dbSDimitry Andric 2935ffd83dbSDimitry Andric StringRef getPassName() const override { 2945ffd83dbSDimitry Andric return "AMDGPUPostLegalizerCombiner"; 2955ffd83dbSDimitry Andric } 2965ffd83dbSDimitry Andric 2975ffd83dbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 2985ffd83dbSDimitry Andric 2995ffd83dbSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 3005ffd83dbSDimitry Andric private: 3015ffd83dbSDimitry Andric bool IsOptNone; 3025ffd83dbSDimitry Andric }; 3035ffd83dbSDimitry Andric } // end anonymous namespace 3045ffd83dbSDimitry Andric 3055ffd83dbSDimitry Andric void AMDGPUPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 3065ffd83dbSDimitry Andric AU.addRequired<TargetPassConfig>(); 3075ffd83dbSDimitry Andric AU.setPreservesCFG(); 3085ffd83dbSDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 3095ffd83dbSDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 3105ffd83dbSDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 3115ffd83dbSDimitry Andric if (!IsOptNone) { 3125ffd83dbSDimitry Andric AU.addRequired<MachineDominatorTree>(); 3135ffd83dbSDimitry Andric AU.addPreserved<MachineDominatorTree>(); 3145ffd83dbSDimitry Andric } 3155ffd83dbSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 3165ffd83dbSDimitry Andric } 3175ffd83dbSDimitry Andric 3185ffd83dbSDimitry Andric AMDGPUPostLegalizerCombiner::AMDGPUPostLegalizerCombiner(bool IsOptNone) 3195ffd83dbSDimitry Andric : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 3205ffd83dbSDimitry Andric initializeAMDGPUPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 3215ffd83dbSDimitry Andric } 3225ffd83dbSDimitry Andric 3235ffd83dbSDimitry Andric bool AMDGPUPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 3245ffd83dbSDimitry Andric if (MF.getProperties().hasProperty( 3255ffd83dbSDimitry Andric MachineFunctionProperties::Property::FailedISel)) 3265ffd83dbSDimitry Andric return false; 3275ffd83dbSDimitry Andric auto *TPC = &getAnalysis<TargetPassConfig>(); 3285ffd83dbSDimitry Andric const Function &F = MF.getFunction(); 3295ffd83dbSDimitry Andric bool EnableOpt = 3305ffd83dbSDimitry Andric MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 3315ffd83dbSDimitry Andric 3325ffd83dbSDimitry Andric const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 3335ffd83dbSDimitry Andric const AMDGPULegalizerInfo *LI 3345ffd83dbSDimitry Andric = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo()); 3355ffd83dbSDimitry Andric 3365ffd83dbSDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 3375ffd83dbSDimitry Andric MachineDominatorTree *MDT = 3385ffd83dbSDimitry Andric IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 3395ffd83dbSDimitry Andric AMDGPUPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 3405ffd83dbSDimitry Andric F.hasMinSize(), LI, KB, MDT); 3415ffd83dbSDimitry Andric Combiner C(PCInfo, TPC); 3425ffd83dbSDimitry Andric return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 3435ffd83dbSDimitry Andric } 3445ffd83dbSDimitry Andric 3455ffd83dbSDimitry Andric char AMDGPUPostLegalizerCombiner::ID = 0; 3465ffd83dbSDimitry Andric INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 3475ffd83dbSDimitry Andric "Combine AMDGPU machine instrs after legalization", 3485ffd83dbSDimitry Andric false, false) 3495ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 3505ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 3515ffd83dbSDimitry Andric INITIALIZE_PASS_END(AMDGPUPostLegalizerCombiner, DEBUG_TYPE, 3525ffd83dbSDimitry Andric "Combine AMDGPU machine instrs after legalization", false, 3535ffd83dbSDimitry Andric false) 3545ffd83dbSDimitry Andric 3555ffd83dbSDimitry Andric namespace llvm { 3565ffd83dbSDimitry Andric FunctionPass *createAMDGPUPostLegalizeCombiner(bool IsOptNone) { 3575ffd83dbSDimitry Andric return new AMDGPUPostLegalizerCombiner(IsOptNone); 3585ffd83dbSDimitry Andric } 3595ffd83dbSDimitry Andric } // end namespace llvm 360