1*5f757f3fSDimitry Andric //=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===// 2*5f757f3fSDimitry Andric // 3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5f757f3fSDimitry Andric // 7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 8*5f757f3fSDimitry Andric /// 9*5f757f3fSDimitry Andric /// \file 10*5f757f3fSDimitry Andric /// Post-legalization combines on generic MachineInstrs. 11*5f757f3fSDimitry Andric /// 12*5f757f3fSDimitry Andric /// The combines here must preserve instruction legality. 13*5f757f3fSDimitry Andric /// 14*5f757f3fSDimitry Andric /// Combines which don't rely on instruction legality should go in the 15*5f757f3fSDimitry Andric /// RISCVPreLegalizerCombiner. 16*5f757f3fSDimitry Andric /// 17*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 18*5f757f3fSDimitry Andric 19*5f757f3fSDimitry Andric #include "RISCVTargetMachine.h" 20*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h" 21*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h" 22*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 23*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 24*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 25*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 26*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 27*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 28*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 29*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 30*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 31*5f757f3fSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 32*5f757f3fSDimitry Andric 33*5f757f3fSDimitry Andric #define GET_GICOMBINER_DEPS 34*5f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 35*5f757f3fSDimitry Andric #undef GET_GICOMBINER_DEPS 36*5f757f3fSDimitry Andric 37*5f757f3fSDimitry Andric #define DEBUG_TYPE "riscv-postlegalizer-combiner" 38*5f757f3fSDimitry Andric 39*5f757f3fSDimitry Andric using namespace llvm; 40*5f757f3fSDimitry Andric 41*5f757f3fSDimitry Andric namespace { 42*5f757f3fSDimitry Andric 43*5f757f3fSDimitry Andric #define GET_GICOMBINER_TYPES 44*5f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 45*5f757f3fSDimitry Andric #undef GET_GICOMBINER_TYPES 46*5f757f3fSDimitry Andric 47*5f757f3fSDimitry Andric class RISCVPostLegalizerCombinerImpl : public Combiner { 48*5f757f3fSDimitry Andric protected: 49*5f757f3fSDimitry Andric // TODO: Make CombinerHelper methods const. 50*5f757f3fSDimitry Andric mutable CombinerHelper Helper; 51*5f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig; 52*5f757f3fSDimitry Andric const RISCVSubtarget &STI; 53*5f757f3fSDimitry Andric 54*5f757f3fSDimitry Andric public: 55*5f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl( 56*5f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 57*5f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 58*5f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig, 59*5f757f3fSDimitry Andric const RISCVSubtarget &STI, MachineDominatorTree *MDT, 60*5f757f3fSDimitry Andric const LegalizerInfo *LI); 61*5f757f3fSDimitry Andric 62*5f757f3fSDimitry Andric static const char *getName() { return "RISCVPostLegalizerCombiner"; } 63*5f757f3fSDimitry Andric 64*5f757f3fSDimitry Andric bool tryCombineAll(MachineInstr &I) const override; 65*5f757f3fSDimitry Andric 66*5f757f3fSDimitry Andric private: 67*5f757f3fSDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS 68*5f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 69*5f757f3fSDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS 70*5f757f3fSDimitry Andric }; 71*5f757f3fSDimitry Andric 72*5f757f3fSDimitry Andric #define GET_GICOMBINER_IMPL 73*5f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 74*5f757f3fSDimitry Andric #undef GET_GICOMBINER_IMPL 75*5f757f3fSDimitry Andric 76*5f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl( 77*5f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 78*5f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 79*5f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig, 80*5f757f3fSDimitry Andric const RISCVSubtarget &STI, MachineDominatorTree *MDT, 81*5f757f3fSDimitry Andric const LegalizerInfo *LI) 82*5f757f3fSDimitry Andric : Combiner(MF, CInfo, TPC, &KB, CSEInfo), 83*5f757f3fSDimitry Andric Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI), 84*5f757f3fSDimitry Andric RuleConfig(RuleConfig), STI(STI), 85*5f757f3fSDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS 86*5f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 87*5f757f3fSDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS 88*5f757f3fSDimitry Andric { 89*5f757f3fSDimitry Andric } 90*5f757f3fSDimitry Andric 91*5f757f3fSDimitry Andric class RISCVPostLegalizerCombiner : public MachineFunctionPass { 92*5f757f3fSDimitry Andric public: 93*5f757f3fSDimitry Andric static char ID; 94*5f757f3fSDimitry Andric 95*5f757f3fSDimitry Andric RISCVPostLegalizerCombiner(); 96*5f757f3fSDimitry Andric 97*5f757f3fSDimitry Andric StringRef getPassName() const override { 98*5f757f3fSDimitry Andric return "RISCVPostLegalizerCombiner"; 99*5f757f3fSDimitry Andric } 100*5f757f3fSDimitry Andric 101*5f757f3fSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 102*5f757f3fSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 103*5f757f3fSDimitry Andric 104*5f757f3fSDimitry Andric private: 105*5f757f3fSDimitry Andric RISCVPostLegalizerCombinerImplRuleConfig RuleConfig; 106*5f757f3fSDimitry Andric }; 107*5f757f3fSDimitry Andric } // end anonymous namespace 108*5f757f3fSDimitry Andric 109*5f757f3fSDimitry Andric void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 110*5f757f3fSDimitry Andric AU.addRequired<TargetPassConfig>(); 111*5f757f3fSDimitry Andric AU.setPreservesCFG(); 112*5f757f3fSDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 113*5f757f3fSDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 114*5f757f3fSDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 115*5f757f3fSDimitry Andric AU.addRequired<MachineDominatorTree>(); 116*5f757f3fSDimitry Andric AU.addPreserved<MachineDominatorTree>(); 117*5f757f3fSDimitry Andric AU.addRequired<GISelCSEAnalysisWrapperPass>(); 118*5f757f3fSDimitry Andric AU.addPreserved<GISelCSEAnalysisWrapperPass>(); 119*5f757f3fSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 120*5f757f3fSDimitry Andric } 121*5f757f3fSDimitry Andric 122*5f757f3fSDimitry Andric RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner() 123*5f757f3fSDimitry Andric : MachineFunctionPass(ID) { 124*5f757f3fSDimitry Andric initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 125*5f757f3fSDimitry Andric 126*5f757f3fSDimitry Andric if (!RuleConfig.parseCommandLineOption()) 127*5f757f3fSDimitry Andric report_fatal_error("Invalid rule identifier"); 128*5f757f3fSDimitry Andric } 129*5f757f3fSDimitry Andric 130*5f757f3fSDimitry Andric bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 131*5f757f3fSDimitry Andric if (MF.getProperties().hasProperty( 132*5f757f3fSDimitry Andric MachineFunctionProperties::Property::FailedISel)) 133*5f757f3fSDimitry Andric return false; 134*5f757f3fSDimitry Andric assert(MF.getProperties().hasProperty( 135*5f757f3fSDimitry Andric MachineFunctionProperties::Property::Legalized) && 136*5f757f3fSDimitry Andric "Expected a legalized function?"); 137*5f757f3fSDimitry Andric auto *TPC = &getAnalysis<TargetPassConfig>(); 138*5f757f3fSDimitry Andric const Function &F = MF.getFunction(); 139*5f757f3fSDimitry Andric bool EnableOpt = 140*5f757f3fSDimitry Andric MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F); 141*5f757f3fSDimitry Andric 142*5f757f3fSDimitry Andric const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 143*5f757f3fSDimitry Andric const auto *LI = ST.getLegalizerInfo(); 144*5f757f3fSDimitry Andric 145*5f757f3fSDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 146*5f757f3fSDimitry Andric MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>(); 147*5f757f3fSDimitry Andric GISelCSEAnalysisWrapper &Wrapper = 148*5f757f3fSDimitry Andric getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper(); 149*5f757f3fSDimitry Andric auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig()); 150*5f757f3fSDimitry Andric 151*5f757f3fSDimitry Andric CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 152*5f757f3fSDimitry Andric /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(), 153*5f757f3fSDimitry Andric F.hasMinSize()); 154*5f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo, 155*5f757f3fSDimitry Andric RuleConfig, ST, MDT, LI); 156*5f757f3fSDimitry Andric return Impl.combineMachineInstrs(); 157*5f757f3fSDimitry Andric } 158*5f757f3fSDimitry Andric 159*5f757f3fSDimitry Andric char RISCVPostLegalizerCombiner::ID = 0; 160*5f757f3fSDimitry Andric INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE, 161*5f757f3fSDimitry Andric "Combine RISC-V MachineInstrs after legalization", false, 162*5f757f3fSDimitry Andric false) 163*5f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 164*5f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 165*5f757f3fSDimitry Andric INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE, 166*5f757f3fSDimitry Andric "Combine RISC-V MachineInstrs after legalization", false, 167*5f757f3fSDimitry Andric false) 168*5f757f3fSDimitry Andric 169*5f757f3fSDimitry Andric namespace llvm { 170*5f757f3fSDimitry Andric FunctionPass *createRISCVPostLegalizerCombiner() { 171*5f757f3fSDimitry Andric return new RISCVPostLegalizerCombiner(); 172*5f757f3fSDimitry Andric } 173*5f757f3fSDimitry Andric } // end namespace llvm 174