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