15f757f3fSDimitry Andric //=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric /// 95f757f3fSDimitry Andric /// \file 105f757f3fSDimitry Andric /// Post-legalization combines on generic MachineInstrs. 115f757f3fSDimitry Andric /// 125f757f3fSDimitry Andric /// The combines here must preserve instruction legality. 135f757f3fSDimitry Andric /// 145f757f3fSDimitry Andric /// Combines which don't rely on instruction legality should go in the 155f757f3fSDimitry Andric /// RISCVPreLegalizerCombiner. 165f757f3fSDimitry Andric /// 175f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 185f757f3fSDimitry Andric 195f757f3fSDimitry Andric #include "RISCVTargetMachine.h" 205f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h" 215f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h" 225f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 235f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 245f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 255f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 265f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 275f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 285f757f3fSDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 295f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 305f757f3fSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 315f757f3fSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 325f757f3fSDimitry Andric 335f757f3fSDimitry Andric #define GET_GICOMBINER_DEPS 345f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 355f757f3fSDimitry Andric #undef GET_GICOMBINER_DEPS 365f757f3fSDimitry Andric 375f757f3fSDimitry Andric #define DEBUG_TYPE "riscv-postlegalizer-combiner" 385f757f3fSDimitry Andric 395f757f3fSDimitry Andric using namespace llvm; 405f757f3fSDimitry Andric 415f757f3fSDimitry Andric namespace { 425f757f3fSDimitry Andric 435f757f3fSDimitry Andric #define GET_GICOMBINER_TYPES 445f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 455f757f3fSDimitry Andric #undef GET_GICOMBINER_TYPES 465f757f3fSDimitry Andric 475f757f3fSDimitry Andric class RISCVPostLegalizerCombinerImpl : public Combiner { 485f757f3fSDimitry Andric protected: 495f757f3fSDimitry Andric // TODO: Make CombinerHelper methods const. 505f757f3fSDimitry Andric mutable CombinerHelper Helper; 515f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig; 525f757f3fSDimitry Andric const RISCVSubtarget &STI; 535f757f3fSDimitry Andric 545f757f3fSDimitry Andric public: 555f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl( 565f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 575f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 585f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig, 595f757f3fSDimitry Andric const RISCVSubtarget &STI, MachineDominatorTree *MDT, 605f757f3fSDimitry Andric const LegalizerInfo *LI); 615f757f3fSDimitry Andric 625f757f3fSDimitry Andric static const char *getName() { return "RISCVPostLegalizerCombiner"; } 635f757f3fSDimitry Andric 645f757f3fSDimitry Andric bool tryCombineAll(MachineInstr &I) const override; 655f757f3fSDimitry Andric 665f757f3fSDimitry Andric private: 675f757f3fSDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS 685f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 695f757f3fSDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS 705f757f3fSDimitry Andric }; 715f757f3fSDimitry Andric 725f757f3fSDimitry Andric #define GET_GICOMBINER_IMPL 735f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 745f757f3fSDimitry Andric #undef GET_GICOMBINER_IMPL 755f757f3fSDimitry Andric 765f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl( 775f757f3fSDimitry Andric MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 785f757f3fSDimitry Andric GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 795f757f3fSDimitry Andric const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig, 805f757f3fSDimitry Andric const RISCVSubtarget &STI, MachineDominatorTree *MDT, 815f757f3fSDimitry Andric const LegalizerInfo *LI) 825f757f3fSDimitry Andric : Combiner(MF, CInfo, TPC, &KB, CSEInfo), 835f757f3fSDimitry Andric Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI), 845f757f3fSDimitry Andric RuleConfig(RuleConfig), STI(STI), 855f757f3fSDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS 865f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc" 875f757f3fSDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS 885f757f3fSDimitry Andric { 895f757f3fSDimitry Andric } 905f757f3fSDimitry Andric 915f757f3fSDimitry Andric class RISCVPostLegalizerCombiner : public MachineFunctionPass { 925f757f3fSDimitry Andric public: 935f757f3fSDimitry Andric static char ID; 945f757f3fSDimitry Andric 955f757f3fSDimitry Andric RISCVPostLegalizerCombiner(); 965f757f3fSDimitry Andric 975f757f3fSDimitry Andric StringRef getPassName() const override { 985f757f3fSDimitry Andric return "RISCVPostLegalizerCombiner"; 995f757f3fSDimitry Andric } 1005f757f3fSDimitry Andric 1015f757f3fSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 1025f757f3fSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 1035f757f3fSDimitry Andric 1045f757f3fSDimitry Andric private: 1055f757f3fSDimitry Andric RISCVPostLegalizerCombinerImplRuleConfig RuleConfig; 1065f757f3fSDimitry Andric }; 1075f757f3fSDimitry Andric } // end anonymous namespace 1085f757f3fSDimitry Andric 1095f757f3fSDimitry Andric void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 1105f757f3fSDimitry Andric AU.addRequired<TargetPassConfig>(); 1115f757f3fSDimitry Andric AU.setPreservesCFG(); 1125f757f3fSDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 1135f757f3fSDimitry Andric AU.addRequired<GISelKnownBitsAnalysis>(); 1145f757f3fSDimitry Andric AU.addPreserved<GISelKnownBitsAnalysis>(); 115*0fca6ea1SDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>(); 116*0fca6ea1SDimitry Andric AU.addPreserved<MachineDominatorTreeWrapperPass>(); 1175f757f3fSDimitry Andric AU.addRequired<GISelCSEAnalysisWrapperPass>(); 1185f757f3fSDimitry Andric AU.addPreserved<GISelCSEAnalysisWrapperPass>(); 1195f757f3fSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 1205f757f3fSDimitry Andric } 1215f757f3fSDimitry Andric 1225f757f3fSDimitry Andric RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner() 1235f757f3fSDimitry Andric : MachineFunctionPass(ID) { 1245f757f3fSDimitry Andric initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 1255f757f3fSDimitry Andric 1265f757f3fSDimitry Andric if (!RuleConfig.parseCommandLineOption()) 1275f757f3fSDimitry Andric report_fatal_error("Invalid rule identifier"); 1285f757f3fSDimitry Andric } 1295f757f3fSDimitry Andric 1305f757f3fSDimitry Andric bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 1315f757f3fSDimitry Andric if (MF.getProperties().hasProperty( 1325f757f3fSDimitry Andric MachineFunctionProperties::Property::FailedISel)) 1335f757f3fSDimitry Andric return false; 1345f757f3fSDimitry Andric assert(MF.getProperties().hasProperty( 1355f757f3fSDimitry Andric MachineFunctionProperties::Property::Legalized) && 1365f757f3fSDimitry Andric "Expected a legalized function?"); 1375f757f3fSDimitry Andric auto *TPC = &getAnalysis<TargetPassConfig>(); 1385f757f3fSDimitry Andric const Function &F = MF.getFunction(); 1395f757f3fSDimitry Andric bool EnableOpt = 1405f757f3fSDimitry Andric MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F); 1415f757f3fSDimitry Andric 1425f757f3fSDimitry Andric const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 1435f757f3fSDimitry Andric const auto *LI = ST.getLegalizerInfo(); 1445f757f3fSDimitry Andric 1455f757f3fSDimitry Andric GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 146*0fca6ea1SDimitry Andric MachineDominatorTree *MDT = 147*0fca6ea1SDimitry Andric &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 1485f757f3fSDimitry Andric GISelCSEAnalysisWrapper &Wrapper = 1495f757f3fSDimitry Andric getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper(); 1505f757f3fSDimitry Andric auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig()); 1515f757f3fSDimitry Andric 1525f757f3fSDimitry Andric CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 1535f757f3fSDimitry Andric /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(), 1545f757f3fSDimitry Andric F.hasMinSize()); 1555f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo, 1565f757f3fSDimitry Andric RuleConfig, ST, MDT, LI); 1575f757f3fSDimitry Andric return Impl.combineMachineInstrs(); 1585f757f3fSDimitry Andric } 1595f757f3fSDimitry Andric 1605f757f3fSDimitry Andric char RISCVPostLegalizerCombiner::ID = 0; 1615f757f3fSDimitry Andric INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE, 1625f757f3fSDimitry Andric "Combine RISC-V MachineInstrs after legalization", false, 1635f757f3fSDimitry Andric false) 1645f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 1655f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 1665f757f3fSDimitry Andric INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE, 1675f757f3fSDimitry Andric "Combine RISC-V MachineInstrs after legalization", false, 1685f757f3fSDimitry Andric false) 1695f757f3fSDimitry Andric 1705f757f3fSDimitry Andric namespace llvm { 1715f757f3fSDimitry Andric FunctionPass *createRISCVPostLegalizerCombiner() { 1725f757f3fSDimitry Andric return new RISCVPostLegalizerCombiner(); 1735f757f3fSDimitry Andric } 1745f757f3fSDimitry Andric } // end namespace llvm 175