1*5f757f3fSDimitry Andric //=== RISCVO0PreLegalizerCombiner.cpp -------------------------------------===// 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 // This pass does combining of machine instructions at the generic MI level, 10*5f757f3fSDimitry Andric // before the legalizer. 11*5f757f3fSDimitry Andric // 12*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 13*5f757f3fSDimitry Andric 14*5f757f3fSDimitry Andric #include "RISCVSubtarget.h" 15*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h" 16*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 17*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 18*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 19*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 20*5f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 21*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 22*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 23*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 24*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 25*5f757f3fSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 26*5f757f3fSDimitry Andric 27*5f757f3fSDimitry Andric #define GET_GICOMBINER_DEPS 28*5f757f3fSDimitry Andric #include "RISCVGenO0PreLegalizeGICombiner.inc" 29*5f757f3fSDimitry Andric #undef GET_GICOMBINER_DEPS 30*5f757f3fSDimitry Andric 31*5f757f3fSDimitry Andric #define DEBUG_TYPE "riscv-O0-prelegalizer-combiner" 32*5f757f3fSDimitry Andric 33*5f757f3fSDimitry Andric using namespace llvm; 34*5f757f3fSDimitry Andric 35*5f757f3fSDimitry Andric namespace { 36*5f757f3fSDimitry Andric #define GET_GICOMBINER_TYPES 37*5f757f3fSDimitry Andric #include "RISCVGenO0PreLegalizeGICombiner.inc" 38*5f757f3fSDimitry Andric #undef GET_GICOMBINER_TYPES 39*5f757f3fSDimitry Andric 40*5f757f3fSDimitry Andric class RISCVO0PreLegalizerCombinerImpl : public Combiner { 41*5f757f3fSDimitry Andric protected: 42*5f757f3fSDimitry Andric // TODO: Make CombinerHelper methods const. 43*5f757f3fSDimitry Andric mutable CombinerHelper Helper; 44*5f757f3fSDimitry Andric const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig; 45*5f757f3fSDimitry Andric const RISCVSubtarget &STI; 46*5f757f3fSDimitry Andric 47*5f757f3fSDimitry Andric public: 48*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombinerImpl( 49*5f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 50*5f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 51*5f757f3fSDimitry Andric const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig, 52*5f757f3fSDimitry Andric const RISCVSubtarget &STI); 53*5f757f3fSDimitry Andric 54*5f757f3fSDimitry Andric static const char *getName() { return "RISCVO0PreLegalizerCombiner"; } 55*5f757f3fSDimitry Andric 56*5f757f3fSDimitry Andric bool tryCombineAll(MachineInstr &I) const override; 57*5f757f3fSDimitry Andric 58*5f757f3fSDimitry Andric private: 59*5f757f3fSDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS 60*5f757f3fSDimitry Andric #include "RISCVGenO0PreLegalizeGICombiner.inc" 61*5f757f3fSDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS 62*5f757f3fSDimitry Andric }; 63*5f757f3fSDimitry Andric 64*5f757f3fSDimitry Andric #define GET_GICOMBINER_IMPL 65*5f757f3fSDimitry Andric #include "RISCVGenO0PreLegalizeGICombiner.inc" 66*5f757f3fSDimitry Andric #undef GET_GICOMBINER_IMPL 67*5f757f3fSDimitry Andric 68*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombinerImpl::RISCVO0PreLegalizerCombinerImpl( 69*5f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 70*5f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 71*5f757f3fSDimitry Andric const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig, 72*5f757f3fSDimitry Andric const RISCVSubtarget &STI) 73*5f757f3fSDimitry Andric : Combiner(MF, CInfo, TPC, &KB, CSEInfo), 74*5f757f3fSDimitry Andric Helper(Observer, B, /*IsPreLegalize*/ true, &KB), RuleConfig(RuleConfig), 75*5f757f3fSDimitry Andric STI(STI), 76*5f757f3fSDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS 77*5f757f3fSDimitry Andric #include "RISCVGenO0PreLegalizeGICombiner.inc" 78*5f757f3fSDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS 79*5f757f3fSDimitry Andric { 80*5f757f3fSDimitry Andric } 81*5f757f3fSDimitry Andric 82*5f757f3fSDimitry Andric // Pass boilerplate 83*5f757f3fSDimitry Andric // ================ 84*5f757f3fSDimitry Andric 85*5f757f3fSDimitry Andric class RISCVO0PreLegalizerCombiner : public MachineFunctionPass { 86*5f757f3fSDimitry Andric public: 87*5f757f3fSDimitry Andric static char ID; 88*5f757f3fSDimitry Andric 89*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombiner(); 90*5f757f3fSDimitry Andric 91*5f757f3fSDimitry Andric StringRef getPassName() const override { 92*5f757f3fSDimitry Andric return "RISCVO0PreLegalizerCombiner"; 93*5f757f3fSDimitry Andric } 94*5f757f3fSDimitry Andric 95*5f757f3fSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 96*5f757f3fSDimitry Andric 97*5f757f3fSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 98*5f757f3fSDimitry Andric 99*5f757f3fSDimitry Andric private: 100*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombinerImplRuleConfig RuleConfig; 101*5f757f3fSDimitry Andric }; 102*5f757f3fSDimitry Andric } // end anonymous namespace 103*5f757f3fSDimitry Andric 104*5f757f3fSDimitry Andric void RISCVO0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 105*5f757f3fSDimitry Andric AU.addRequired<TargetPassConfig>(); 106*5f757f3fSDimitry Andric AU.setPreservesCFG(); 107*5f757f3fSDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 108*5f757f3fSDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 109*5f757f3fSDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 110*5f757f3fSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 111*5f757f3fSDimitry Andric } 112*5f757f3fSDimitry Andric 113*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombiner::RISCVO0PreLegalizerCombiner() 114*5f757f3fSDimitry Andric : MachineFunctionPass(ID) { 115*5f757f3fSDimitry Andric initializeRISCVO0PreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 116*5f757f3fSDimitry Andric 117*5f757f3fSDimitry Andric if (!RuleConfig.parseCommandLineOption()) 118*5f757f3fSDimitry Andric report_fatal_error("Invalid rule identifier"); 119*5f757f3fSDimitry Andric } 120*5f757f3fSDimitry Andric 121*5f757f3fSDimitry Andric bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 122*5f757f3fSDimitry Andric if (MF.getProperties().hasProperty( 123*5f757f3fSDimitry Andric MachineFunctionProperties::Property::FailedISel)) 124*5f757f3fSDimitry Andric return false; 125*5f757f3fSDimitry Andric auto &TPC = getAnalysis<TargetPassConfig>(); 126*5f757f3fSDimitry Andric 127*5f757f3fSDimitry Andric const Function &F = MF.getFunction(); 128*5f757f3fSDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 129*5f757f3fSDimitry Andric 130*5f757f3fSDimitry Andric const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 131*5f757f3fSDimitry Andric 132*5f757f3fSDimitry Andric CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 133*5f757f3fSDimitry Andric /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false, 134*5f757f3fSDimitry Andric F.hasOptSize(), F.hasMinSize()); 135*5f757f3fSDimitry Andric RISCVO0PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *KB, 136*5f757f3fSDimitry Andric /*CSEInfo*/ nullptr, RuleConfig, ST); 137*5f757f3fSDimitry Andric return Impl.combineMachineInstrs(); 138*5f757f3fSDimitry Andric } 139*5f757f3fSDimitry Andric 140*5f757f3fSDimitry Andric char RISCVO0PreLegalizerCombiner::ID = 0; 141*5f757f3fSDimitry Andric INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE, 142*5f757f3fSDimitry Andric "Combine RISC-V machine instrs before legalization", false, 143*5f757f3fSDimitry Andric false) 144*5f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 145*5f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 146*5f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass) 147*5f757f3fSDimitry Andric INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE, 148*5f757f3fSDimitry Andric "Combine RISC-V machine instrs before legalization", false, 149*5f757f3fSDimitry Andric false) 150*5f757f3fSDimitry Andric 151*5f757f3fSDimitry Andric namespace llvm { 152*5f757f3fSDimitry Andric FunctionPass *createRISCVO0PreLegalizerCombiner() { 153*5f757f3fSDimitry Andric return new RISCVO0PreLegalizerCombiner(); 154*5f757f3fSDimitry Andric } 155*5f757f3fSDimitry Andric } // end namespace llvm 156