1 //=== lib/CodeGen/GlobalISel/MipsPostLegalizerCombiner.cpp ----------------===// 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 // This pass does combining of machine instructions at the generic MI level, 10 // after the legalizer. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/MipsMCTargetDesc.h" 15 #include "Mips.h" 16 #include "MipsLegalizerInfo.h" 17 #include "MipsSubtarget.h" 18 #include "llvm/CodeGen/GlobalISel/Combiner.h" 19 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 20 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 21 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" 22 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 23 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 24 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 25 #include "llvm/CodeGen/MachineDominators.h" 26 #include "llvm/CodeGen/TargetPassConfig.h" 27 #include "llvm/Target/TargetMachine.h" 28 29 #define GET_GICOMBINER_DEPS 30 #include "MipsGenPostLegalizeGICombiner.inc" 31 #undef GET_GICOMBINER_DEPS 32 33 #define DEBUG_TYPE "mips-postlegalizer-combiner" 34 35 using namespace llvm; 36 using namespace MIPatternMatch; 37 38 namespace { 39 #define GET_GICOMBINER_TYPES 40 #include "MipsGenPostLegalizeGICombiner.inc" 41 #undef GET_GICOMBINER_TYPES 42 43 class MipsPostLegalizerCombinerImpl : public GIMatchTableExecutor { 44 protected: 45 CombinerHelper &Helper; 46 const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig; 47 48 const MipsSubtarget &STI; 49 GISelChangeObserver &Observer; 50 MachineIRBuilder &B; 51 MachineFunction &MF; 52 53 MachineRegisterInfo &MRI; 54 55 public: 56 MipsPostLegalizerCombinerImpl( 57 const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 58 const MipsSubtarget &STI, GISelChangeObserver &Observer, 59 MachineIRBuilder &B, CombinerHelper &Helper); 60 61 static const char *getName() { return "MipsPostLegalizerCombiner"; } 62 63 bool tryCombineAll(MachineInstr &I) const; 64 65 private: 66 #define GET_GICOMBINER_CLASS_MEMBERS 67 #include "MipsGenPostLegalizeGICombiner.inc" 68 #undef GET_GICOMBINER_CLASS_MEMBERS 69 }; 70 71 #define GET_GICOMBINER_IMPL 72 #include "MipsGenPostLegalizeGICombiner.inc" 73 #undef GET_GICOMBINER_IMPL 74 75 MipsPostLegalizerCombinerImpl::MipsPostLegalizerCombinerImpl( 76 const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 77 const MipsSubtarget &STI, GISelChangeObserver &Observer, 78 MachineIRBuilder &B, CombinerHelper &Helper) 79 : Helper(Helper), RuleConfig(RuleConfig), STI(STI), Observer(Observer), 80 B(B), MF(B.getMF()), MRI(*B.getMRI()), 81 #define GET_GICOMBINER_CONSTRUCTOR_INITS 82 #include "MipsGenPostLegalizeGICombiner.inc" 83 #undef GET_GICOMBINER_CONSTRUCTOR_INITS 84 { 85 } 86 87 class MipsPostLegalizerCombinerInfo final : public CombinerInfo { 88 GISelKnownBits *KB; 89 90 public: 91 MipsPostLegalizerCombinerImplRuleConfig RuleConfig; 92 93 MipsPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 94 GISelKnownBits *KB, const MipsLegalizerInfo *LI) 95 : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 96 /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 97 KB(KB) { 98 if (!RuleConfig.parseCommandLineOption()) 99 report_fatal_error("Invalid rule identifier"); 100 } 101 102 bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 103 MachineIRBuilder &B) const override; 104 }; 105 106 bool MipsPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 107 MachineInstr &MI, 108 MachineIRBuilder &B) const { 109 const auto &STI = MI.getMF()->getSubtarget<MipsSubtarget>(); 110 CombinerHelper Helper(Observer, B, /* IsPreLegalize*/ false, KB, 111 /*DominatorTree*/ nullptr, LInfo); 112 MipsPostLegalizerCombinerImpl Impl(RuleConfig, STI, Observer, B, Helper); 113 Impl.setupMF(*MI.getMF(), KB); 114 return Impl.tryCombineAll(MI); 115 } 116 117 // Pass boilerplate 118 // ================ 119 120 class MipsPostLegalizerCombiner : public MachineFunctionPass { 121 public: 122 static char ID; 123 124 MipsPostLegalizerCombiner(bool IsOptNone = false); 125 126 StringRef getPassName() const override { 127 return "MipsPostLegalizerCombiner"; 128 } 129 130 bool runOnMachineFunction(MachineFunction &MF) override; 131 132 void getAnalysisUsage(AnalysisUsage &AU) const override; 133 134 private: 135 bool IsOptNone; 136 }; 137 } // end anonymous namespace 138 139 void MipsPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 140 AU.addRequired<TargetPassConfig>(); 141 AU.setPreservesCFG(); 142 getSelectionDAGFallbackAnalysisUsage(AU); 143 AU.addRequired<GISelKnownBitsAnalysis>(); 144 AU.addPreserved<GISelKnownBitsAnalysis>(); 145 if (!IsOptNone) { 146 AU.addRequired<MachineDominatorTree>(); 147 AU.addPreserved<MachineDominatorTree>(); 148 } 149 MachineFunctionPass::getAnalysisUsage(AU); 150 } 151 152 MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone) 153 : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 154 initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 155 } 156 157 bool MipsPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 158 if (MF.getProperties().hasProperty( 159 MachineFunctionProperties::Property::FailedISel)) 160 return false; 161 auto *TPC = &getAnalysis<TargetPassConfig>(); 162 const Function &F = MF.getFunction(); 163 bool EnableOpt = 164 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 165 166 const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>(); 167 const MipsLegalizerInfo *LI = 168 static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo()); 169 170 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 171 MipsPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 172 F.hasMinSize(), KB, LI); 173 Combiner C(PCInfo, TPC); 174 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 175 } 176 177 char MipsPostLegalizerCombiner::ID = 0; 178 INITIALIZE_PASS_BEGIN(MipsPostLegalizerCombiner, DEBUG_TYPE, 179 "Combine Mips machine instrs after legalization", false, 180 false) 181 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 182 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 183 INITIALIZE_PASS_END(MipsPostLegalizerCombiner, DEBUG_TYPE, 184 "Combine Mips machine instrs after legalization", false, 185 false) 186 187 namespace llvm { 188 FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) { 189 return new MipsPostLegalizerCombiner(IsOptNone); 190 } 191 } // end namespace llvm 192