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" 2106c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 2281ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 2381ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 2481ad6265SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 2581ad6265SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 2681ad6265SDimitry Andric #include "llvm/Target/TargetMachine.h" 2781ad6265SDimitry Andric 2806c3fb27SDimitry Andric #define GET_GICOMBINER_DEPS 2906c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 3006c3fb27SDimitry Andric #undef GET_GICOMBINER_DEPS 3106c3fb27SDimitry Andric 3281ad6265SDimitry Andric #define DEBUG_TYPE "mips-postlegalizer-combiner" 3381ad6265SDimitry Andric 3481ad6265SDimitry Andric using namespace llvm; 3581ad6265SDimitry Andric using namespace MIPatternMatch; 3681ad6265SDimitry Andric 3781ad6265SDimitry Andric namespace { 3806c3fb27SDimitry Andric #define GET_GICOMBINER_TYPES 3981ad6265SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 4006c3fb27SDimitry Andric #undef GET_GICOMBINER_TYPES 4106c3fb27SDimitry Andric 425f757f3fSDimitry Andric class MipsPostLegalizerCombinerImpl : public Combiner { 4306c3fb27SDimitry Andric protected: 4406c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig; 4506c3fb27SDimitry Andric const MipsSubtarget &STI; 465f757f3fSDimitry Andric // TODO: Make CombinerHelper methods const. 475f757f3fSDimitry Andric mutable CombinerHelper Helper; 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric public: 5006c3fb27SDimitry Andric MipsPostLegalizerCombinerImpl( 515f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 525f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 5306c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 545f757f3fSDimitry Andric const MipsSubtarget &STI, MachineDominatorTree *MDT, 555f757f3fSDimitry Andric const LegalizerInfo *LI); 5606c3fb27SDimitry Andric 5706c3fb27SDimitry Andric static const char *getName() { return "MipsPostLegalizerCombiner"; } 5806c3fb27SDimitry Andric 595f757f3fSDimitry Andric bool tryCombineAll(MachineInstr &I) const override; 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric private: 6206c3fb27SDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS 6306c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 6406c3fb27SDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS 6506c3fb27SDimitry Andric }; 6606c3fb27SDimitry Andric 6706c3fb27SDimitry Andric #define GET_GICOMBINER_IMPL 6806c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 6906c3fb27SDimitry Andric #undef GET_GICOMBINER_IMPL 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric MipsPostLegalizerCombinerImpl::MipsPostLegalizerCombinerImpl( 725f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 735f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 7406c3fb27SDimitry Andric const MipsPostLegalizerCombinerImplRuleConfig &RuleConfig, 755f757f3fSDimitry Andric const MipsSubtarget &STI, MachineDominatorTree *MDT, 765f757f3fSDimitry Andric const LegalizerInfo *LI) 775f757f3fSDimitry Andric : Combiner(MF, CInfo, TPC, &KB, CSEInfo), RuleConfig(RuleConfig), STI(STI), 785f757f3fSDimitry Andric Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI), 7906c3fb27SDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS 8006c3fb27SDimitry Andric #include "MipsGenPostLegalizeGICombiner.inc" 8106c3fb27SDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS 8206c3fb27SDimitry Andric { 8306c3fb27SDimitry Andric } 8481ad6265SDimitry Andric 8581ad6265SDimitry Andric // Pass boilerplate 8681ad6265SDimitry Andric // ================ 8781ad6265SDimitry Andric 8881ad6265SDimitry Andric class MipsPostLegalizerCombiner : public MachineFunctionPass { 8981ad6265SDimitry Andric public: 9081ad6265SDimitry Andric static char ID; 9181ad6265SDimitry Andric 9281ad6265SDimitry Andric MipsPostLegalizerCombiner(bool IsOptNone = false); 9381ad6265SDimitry Andric 945f757f3fSDimitry Andric StringRef getPassName() const override { return "MipsPostLegalizerCombiner"; } 9581ad6265SDimitry Andric 9681ad6265SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 9781ad6265SDimitry Andric 9881ad6265SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 9981ad6265SDimitry Andric 10081ad6265SDimitry Andric private: 10181ad6265SDimitry Andric bool IsOptNone; 1025f757f3fSDimitry Andric MipsPostLegalizerCombinerImplRuleConfig RuleConfig; 10381ad6265SDimitry Andric }; 10481ad6265SDimitry Andric } // end anonymous namespace 10581ad6265SDimitry Andric 10681ad6265SDimitry Andric void MipsPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 10781ad6265SDimitry Andric AU.addRequired<TargetPassConfig>(); 10881ad6265SDimitry Andric AU.setPreservesCFG(); 10981ad6265SDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 11081ad6265SDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 11181ad6265SDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 11281ad6265SDimitry Andric if (!IsOptNone) { 113*0fca6ea1SDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>(); 114*0fca6ea1SDimitry Andric AU.addPreserved<MachineDominatorTreeWrapperPass>(); 11581ad6265SDimitry Andric } 11681ad6265SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 11781ad6265SDimitry Andric } 11881ad6265SDimitry Andric 11981ad6265SDimitry Andric MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone) 12081ad6265SDimitry Andric : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 12181ad6265SDimitry Andric initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 1225f757f3fSDimitry Andric 1235f757f3fSDimitry Andric if (!RuleConfig.parseCommandLineOption()) 1245f757f3fSDimitry Andric report_fatal_error("Invalid rule identifier"); 12581ad6265SDimitry Andric } 12681ad6265SDimitry Andric 12781ad6265SDimitry Andric bool MipsPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 12881ad6265SDimitry Andric if (MF.getProperties().hasProperty( 12981ad6265SDimitry Andric MachineFunctionProperties::Property::FailedISel)) 13081ad6265SDimitry Andric return false; 13181ad6265SDimitry Andric auto *TPC = &getAnalysis<TargetPassConfig>(); 13281ad6265SDimitry Andric const Function &F = MF.getFunction(); 13381ad6265SDimitry Andric bool EnableOpt = 1345f757f3fSDimitry Andric MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F); 13581ad6265SDimitry Andric 13681ad6265SDimitry Andric const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>(); 13781ad6265SDimitry Andric const MipsLegalizerInfo *LI = 13881ad6265SDimitry Andric static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo()); 13981ad6265SDimitry Andric 14081ad6265SDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 1415f757f3fSDimitry Andric MachineDominatorTree *MDT = 142*0fca6ea1SDimitry Andric IsOptNone ? nullptr 143*0fca6ea1SDimitry Andric : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 1445f757f3fSDimitry Andric CombinerInfo CInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 1455f757f3fSDimitry Andric LI, EnableOpt, F.hasOptSize(), F.hasMinSize()); 1465f757f3fSDimitry Andric MipsPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, /*CSEInfo*/ nullptr, 1475f757f3fSDimitry Andric RuleConfig, ST, MDT, LI); 1485f757f3fSDimitry Andric return Impl.combineMachineInstrs(); 14981ad6265SDimitry Andric } 15081ad6265SDimitry Andric 15181ad6265SDimitry Andric char MipsPostLegalizerCombiner::ID = 0; 15281ad6265SDimitry Andric INITIALIZE_PASS_BEGIN(MipsPostLegalizerCombiner, DEBUG_TYPE, 15381ad6265SDimitry Andric "Combine Mips machine instrs after legalization", false, 15481ad6265SDimitry Andric false) 15581ad6265SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 15681ad6265SDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 15781ad6265SDimitry Andric INITIALIZE_PASS_END(MipsPostLegalizerCombiner, DEBUG_TYPE, 15881ad6265SDimitry Andric "Combine Mips machine instrs after legalization", false, 15981ad6265SDimitry Andric false) 16081ad6265SDimitry Andric 16181ad6265SDimitry Andric namespace llvm { 16281ad6265SDimitry Andric FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) { 16381ad6265SDimitry Andric return new MipsPostLegalizerCombiner(IsOptNone); 16481ad6265SDimitry Andric } 16581ad6265SDimitry Andric } // end namespace llvm 166