181ad6265SDimitry Andric //=== lib/CodeGen/GlobalISel/MipsPostLegalizerCombiner.cpp ----------------===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // This pass does combining of machine instructions at the generic MI level, 1081ad6265SDimitry Andric // after the legalizer. 1181ad6265SDimitry Andric // 1281ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1381ad6265SDimitry Andric 1481ad6265SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h" 1581ad6265SDimitry Andric #include "Mips.h" 1681ad6265SDimitry Andric #include "MipsLegalizerInfo.h" 1781ad6265SDimitry Andric #include "MipsSubtarget.h" 1881ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h" 1981ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 2081ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 21*06c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" 22*06c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 2381ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 2481ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 2581ad6265SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 2681ad6265SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 2781ad6265SDimitry Andric #include "llvm/Target/TargetMachine.h" 2881ad6265SDimitry Andric 29*06c3fb27SDimitry Andric #define GET_GICOMBINER_DEPS 30*06c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 31*06c3fb27SDimitry Andric #undef GET_GICOMBINER_DEPS 32*06c3fb27SDimitry Andric 3381ad6265SDimitry Andric #define DEBUG_TYPE "mips-postlegalizer-combiner" 3481ad6265SDimitry Andric 3581ad6265SDimitry Andric using namespace llvm; 3681ad6265SDimitry Andric using namespace MIPatternMatch; 3781ad6265SDimitry Andric 3881ad6265SDimitry Andric namespace { 39*06c3fb27SDimitry Andric #define GET_GICOMBINER_TYPES 4081ad6265SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 41*06c3fb27SDimitry Andric #undef GET_GICOMBINER_TYPES 42*06c3fb27SDimitry Andric 43*06c3fb27SDimitry Andric class MipsPostLegalizerCombinerImpl : public GIMatchTableExecutor { 44*06c3fb27SDimitry Andric protected: 45*06c3fb27SDimitry Andric CombinerHelper &Helper; 46*06c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig; 47*06c3fb27SDimitry Andric 48*06c3fb27SDimitry Andric const MipsSubtarget &STI; 49*06c3fb27SDimitry Andric GISelChangeObserver &Observer; 50*06c3fb27SDimitry Andric MachineIRBuilder &B; 51*06c3fb27SDimitry Andric MachineFunction &MF; 52*06c3fb27SDimitry Andric 53*06c3fb27SDimitry Andric MachineRegisterInfo &MRI; 54*06c3fb27SDimitry Andric 55*06c3fb27SDimitry Andric public: 56*06c3fb27SDimitry Andric MipsPostLegalizerCombinerImpl( 57*06c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 58*06c3fb27SDimitry Andric const MipsSubtarget &STI, GISelChangeObserver &Observer, 59*06c3fb27SDimitry Andric MachineIRBuilder &B, CombinerHelper &Helper); 60*06c3fb27SDimitry Andric 61*06c3fb27SDimitry Andric static const char *getName() { return "MipsPostLegalizerCombiner"; } 62*06c3fb27SDimitry Andric 63*06c3fb27SDimitry Andric bool tryCombineAll(MachineInstr &I) const; 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric private: 66*06c3fb27SDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS 67*06c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 68*06c3fb27SDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS 69*06c3fb27SDimitry Andric }; 70*06c3fb27SDimitry Andric 71*06c3fb27SDimitry Andric #define GET_GICOMBINER_IMPL 72*06c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 73*06c3fb27SDimitry Andric #undef GET_GICOMBINER_IMPL 74*06c3fb27SDimitry Andric 75*06c3fb27SDimitry Andric MipsPostLegalizerCombinerImpl::MipsPostLegalizerCombinerImpl( 76*06c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 77*06c3fb27SDimitry Andric const MipsSubtarget &STI, GISelChangeObserver &Observer, 78*06c3fb27SDimitry Andric MachineIRBuilder &B, CombinerHelper &Helper) 79*06c3fb27SDimitry Andric : Helper(Helper), RuleConfig(RuleConfig), STI(STI), Observer(Observer), 80*06c3fb27SDimitry Andric B(B), MF(B.getMF()), MRI(*B.getMRI()), 81*06c3fb27SDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS 82*06c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 83*06c3fb27SDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS 84*06c3fb27SDimitry Andric { 85*06c3fb27SDimitry Andric } 8681ad6265SDimitry Andric 8781ad6265SDimitry Andric class MipsPostLegalizerCombinerInfo final : public CombinerInfo { 8881ad6265SDimitry Andric GISelKnownBits *KB; 8981ad6265SDimitry Andric 9081ad6265SDimitry Andric public: 91*06c3fb27SDimitry Andric MipsPostLegalizerCombinerImplRuleConfig RuleConfig; 9281ad6265SDimitry Andric 9381ad6265SDimitry Andric MipsPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 9481ad6265SDimitry Andric GISelKnownBits *KB, const MipsLegalizerInfo *LI) 9581ad6265SDimitry Andric : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 9681ad6265SDimitry Andric /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 9781ad6265SDimitry Andric KB(KB) { 98*06c3fb27SDimitry Andric if (!RuleConfig.parseCommandLineOption()) 9981ad6265SDimitry Andric report_fatal_error("Invalid rule identifier"); 10081ad6265SDimitry Andric } 10181ad6265SDimitry Andric 10281ad6265SDimitry Andric bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 10381ad6265SDimitry Andric MachineIRBuilder &B) const override; 10481ad6265SDimitry Andric }; 10581ad6265SDimitry Andric 10681ad6265SDimitry Andric bool MipsPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 10781ad6265SDimitry Andric MachineInstr &MI, 10881ad6265SDimitry Andric MachineIRBuilder &B) const { 109*06c3fb27SDimitry Andric const auto &STI = MI.getMF()->getSubtarget<MipsSubtarget>(); 110bdd1243dSDimitry Andric CombinerHelper Helper(Observer, B, /* IsPreLegalize*/ false, KB, 11181ad6265SDimitry Andric /*DominatorTree*/ nullptr, LInfo); 112*06c3fb27SDimitry Andric MipsPostLegalizerCombinerImpl Impl(RuleConfig, STI, Observer, B, Helper); 113*06c3fb27SDimitry Andric Impl.setupMF(*MI.getMF(), KB); 114*06c3fb27SDimitry Andric return Impl.tryCombineAll(MI); 11581ad6265SDimitry Andric } 11681ad6265SDimitry Andric 11781ad6265SDimitry Andric // Pass boilerplate 11881ad6265SDimitry Andric // ================ 11981ad6265SDimitry Andric 12081ad6265SDimitry Andric class MipsPostLegalizerCombiner : public MachineFunctionPass { 12181ad6265SDimitry Andric public: 12281ad6265SDimitry Andric static char ID; 12381ad6265SDimitry Andric 12481ad6265SDimitry Andric MipsPostLegalizerCombiner(bool IsOptNone = false); 12581ad6265SDimitry Andric 12681ad6265SDimitry Andric StringRef getPassName() const override { 12781ad6265SDimitry Andric return "MipsPostLegalizerCombiner"; 12881ad6265SDimitry Andric } 12981ad6265SDimitry Andric 13081ad6265SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 13181ad6265SDimitry Andric 13281ad6265SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 13381ad6265SDimitry Andric 13481ad6265SDimitry Andric private: 13581ad6265SDimitry Andric bool IsOptNone; 13681ad6265SDimitry Andric }; 13781ad6265SDimitry Andric } // end anonymous namespace 13881ad6265SDimitry Andric 13981ad6265SDimitry Andric void MipsPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 14081ad6265SDimitry Andric AU.addRequired<TargetPassConfig>(); 14181ad6265SDimitry Andric AU.setPreservesCFG(); 14281ad6265SDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 14381ad6265SDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 14481ad6265SDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 14581ad6265SDimitry Andric if (!IsOptNone) { 14681ad6265SDimitry Andric AU.addRequired<MachineDominatorTree>(); 14781ad6265SDimitry Andric AU.addPreserved<MachineDominatorTree>(); 14881ad6265SDimitry Andric } 14981ad6265SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 15081ad6265SDimitry Andric } 15181ad6265SDimitry Andric 15281ad6265SDimitry Andric MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone) 15381ad6265SDimitry Andric : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 15481ad6265SDimitry Andric initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 15581ad6265SDimitry Andric } 15681ad6265SDimitry Andric 15781ad6265SDimitry Andric bool MipsPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 15881ad6265SDimitry Andric if (MF.getProperties().hasProperty( 15981ad6265SDimitry Andric MachineFunctionProperties::Property::FailedISel)) 16081ad6265SDimitry Andric return false; 16181ad6265SDimitry Andric auto *TPC = &getAnalysis<TargetPassConfig>(); 16281ad6265SDimitry Andric const Function &F = MF.getFunction(); 16381ad6265SDimitry Andric bool EnableOpt = 16481ad6265SDimitry Andric MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 16581ad6265SDimitry Andric 16681ad6265SDimitry Andric const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>(); 16781ad6265SDimitry Andric const MipsLegalizerInfo *LI = 16881ad6265SDimitry Andric static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo()); 16981ad6265SDimitry Andric 17081ad6265SDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 17181ad6265SDimitry Andric MipsPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 17281ad6265SDimitry Andric F.hasMinSize(), KB, LI); 17381ad6265SDimitry Andric Combiner C(PCInfo, TPC); 17481ad6265SDimitry Andric return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 17581ad6265SDimitry Andric } 17681ad6265SDimitry Andric 17781ad6265SDimitry Andric char MipsPostLegalizerCombiner::ID = 0; 17881ad6265SDimitry Andric INITIALIZE_PASS_BEGIN(MipsPostLegalizerCombiner, DEBUG_TYPE, 17981ad6265SDimitry Andric "Combine Mips machine instrs after legalization", false, 18081ad6265SDimitry Andric false) 18181ad6265SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 18281ad6265SDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 18381ad6265SDimitry Andric INITIALIZE_PASS_END(MipsPostLegalizerCombiner, DEBUG_TYPE, 18481ad6265SDimitry Andric "Combine Mips machine instrs after legalization", false, 18581ad6265SDimitry Andric false) 18681ad6265SDimitry Andric 18781ad6265SDimitry Andric namespace llvm { 18881ad6265SDimitry Andric FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) { 18981ad6265SDimitry Andric return new MipsPostLegalizerCombiner(IsOptNone); 19081ad6265SDimitry Andric } 19181ad6265SDimitry Andric } // end namespace llvm 192